Skip to content

Commit 63dcdf7

Browse files
authored
fix(entity_reference): Return emtpy arrays instead of NULL (#1265)
1 parent 356d0b6 commit 63dcdf7

5 files changed

Lines changed: 115 additions & 22 deletions

File tree

src/Plugin/GraphQL/DataProducer/Field/EntityReference.php

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -145,11 +145,13 @@ public function __construct(
145145
* @param string|null $accessOperation
146146
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
147147
*
148-
* @return \GraphQL\Deferred|null
148+
* @return \GraphQL\Deferred|array
149+
* A promise that will return referenced entities or empty array if there
150+
* aren't any.
149151
*/
150152
public function resolve(EntityInterface $entity, $field, ?string $language, ?array $bundles, ?bool $access, ?AccountInterface $accessUser, ?string $accessOperation, FieldContext $context) {
151153
if (!$entity instanceof FieldableEntityInterface || !$entity->hasField($field)) {
152-
return NULL;
154+
return [];
153155
}
154156

155157
$definition = $entity->getFieldDefinition($field);
@@ -166,7 +168,7 @@ public function resolve(EntityInterface $entity, $field, ?string $language, ?arr
166168
});
167169
}
168170

169-
return NULL;
171+
return [];
170172
}
171173

172174
}

src/Plugin/GraphQL/DataProducer/Field/EntityReferenceLayoutRevisions.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
* id = "entity_reference_layout_revisions",
2222
* name = @Translation("Entity reference layout revisions"),
2323
* description = @Translation("Loads entities from an entity reference layout revisions field."),
24-
* provider = "entity_reference_layout",
2524
* produces = @ContextDefinition("entity",
2625
* label = @Translation("Entity"),
2726
* multiple = TRUE
@@ -143,17 +142,18 @@ public function __construct(
143142
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
144143
* The caching context related to the current field.
145144
*
146-
* @return \GraphQL\Deferred|null
147-
* A promise that will return entities or NULL if there aren't any.
145+
* @return \GraphQL\Deferred|array
146+
* A promise that will return referenced entities or empty array if there
147+
* aren't any.
148148
*/
149-
public function resolve(EntityInterface $entity, string $field, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, FieldContext $context): ?Deferred {
149+
public function resolve(EntityInterface $entity, string $field, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, FieldContext $context) {
150150
if (!$entity instanceof FieldableEntityInterface || !$entity->hasField($field)) {
151-
return NULL;
151+
return [];
152152
}
153153

154154
$definition = $entity->getFieldDefinition($field);
155155
if ($definition->getType() !== 'entity_reference_layout_revisioned') {
156-
return NULL;
156+
return [];
157157
}
158158

159159
$definition = $entity->getFieldDefinition($field);
@@ -170,7 +170,7 @@ public function resolve(EntityInterface $entity, string $field, ?string $languag
170170
});
171171
}
172172

173-
return NULL;
173+
return [];
174174
}
175175

176176
}

src/Plugin/GraphQL/DataProducer/Field/EntityReferenceRevisions.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,6 @@
2121
* id = "entity_reference_revisions",
2222
* name = @Translation("Entity reference revisions"),
2323
* description = @Translation("Loads entities from an entity reference revisions field."),
24-
* provider = "entity_reference_revisions",
2524
* produces = @ContextDefinition("entity",
2625
* label = @Translation("Entity"),
2726
* multiple = TRUE
@@ -143,17 +142,18 @@ public function __construct(
143142
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
144143
* The caching context related to the current field.
145144
*
146-
* @return \GraphQL\Deferred|null
147-
* A promise that will return entities or NULL if there aren't any.
145+
* @return \GraphQL\Deferred|array
146+
* A promise that will return referenced entities or empty array if there
147+
* aren't any.
148148
*/
149-
public function resolve(EntityInterface $entity, string $field, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, FieldContext $context): ?Deferred {
149+
public function resolve(EntityInterface $entity, string $field, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, FieldContext $context) {
150150
if (!$entity instanceof FieldableEntityInterface || !$entity->hasField($field)) {
151-
return NULL;
151+
return [];
152152
}
153153

154154
$definition = $entity->getFieldDefinition($field);
155155
if ($definition->getType() !== 'entity_reference_revisions') {
156-
return NULL;
156+
return [];
157157
}
158158

159159
$definition = $entity->getFieldDefinition($field);
@@ -170,7 +170,7 @@ public function resolve(EntityInterface $entity, string $field, ?string $languag
170170
});
171171
}
172172

173-
return NULL;
173+
return [];
174174
}
175175

176176
}

src/Plugin/GraphQL/DataProducer/Field/EntityReferenceTrait.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,10 @@ trait EntityReferenceTrait {
3434
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context
3535
* The caching context related to the current field.
3636
*
37-
* @return \Drupal\Core\Entity\EntityInterface[]|null
38-
* The list of references entities. Or NULL.
37+
* @return \Drupal\Core\Entity\EntityInterface[]
38+
* The list of references entities.
3939
*/
40-
protected function getReferencedEntities(string $type, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, \Closure $resolver, FieldContext $context): ?array {
40+
protected function getReferencedEntities(string $type, ?string $language, ?array $bundles, bool $access, ?AccountInterface $accessUser, string $accessOperation, \Closure $resolver, FieldContext $context): array {
4141
$entities = $resolver() ?: [];
4242

4343
if (isset($bundles)) {
@@ -57,7 +57,7 @@ protected function getReferencedEntities(string $type, ?string $language, ?array
5757
/** @var \Drupal\Core\Entity\EntityTypeInterface $type */
5858
$tags = $type->getListCacheTags();
5959
$context->addCacheTags($tags);
60-
return NULL;
60+
return [];
6161
}
6262

6363
return $entities;

tests/src/Kernel/DataProducer/EntityReferenceTest.php

Lines changed: 92 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@
1212
use Drupal\user\UserInterface;
1313

1414
/**
15-
* Data producers Field test class.
15+
* Tests the entity_reference data producers.
1616
*
1717
* @group graphql
1818
*/
@@ -92,4 +92,95 @@ public function testResolveEntityReference(): void {
9292
$this->assertEquals('Dolor2 French', reset($result)->label());
9393
}
9494

95+
/**
96+
* Tests that a given data producer returns an empty array.
97+
*
98+
* @dataProvider emptyResultsProvider
99+
*/
100+
public function testEmptyResults(string $data_producer, array $contexts): void {
101+
$node = Node::create([
102+
'title' => 'Dolor',
103+
'type' => 'test1',
104+
]);
105+
$node->save();
106+
$contexts['entity'] = $node;
107+
108+
$result = $this->executeDataProducer($data_producer, $contexts);
109+
$this->assertIsArray($result);
110+
$this->assertEmpty($result);
111+
}
112+
113+
/**
114+
* Data provider for testEmptyResults().
115+
*/
116+
public function emptyResultsProvider(): array {
117+
return [
118+
// Test that an empty reference field returns an empty array.
119+
['entity_reference', [
120+
'field' => 'field_test1_to_test2',
121+
'access' => TRUE,
122+
'access_operation' => 'view',
123+
],
124+
],
125+
// Test that an invalid field name returns an empty array.
126+
['entity_reference', [
127+
'field' => 'does_not_exist',
128+
'access' => TRUE,
129+
'access_operation' => 'view',
130+
],
131+
],
132+
// Test that an invalid field type returns an empty array.
133+
['entity_reference', [
134+
'field' => 'title',
135+
'access' => TRUE,
136+
'access_operation' => 'view',
137+
],
138+
],
139+
// Same test set for the entity_reference_revisions data producer.
140+
// Test that an empty reference field returns an empty array.
141+
['entity_reference_revisions', [
142+
'field' => 'field_test1_to_test2',
143+
'access' => TRUE,
144+
'access_operation' => 'view',
145+
],
146+
],
147+
// Test that an invalid field name returns an empty array.
148+
['entity_reference_revisions', [
149+
'field' => 'does_not_exist',
150+
'access' => TRUE,
151+
'access_operation' => 'view',
152+
],
153+
],
154+
// Test that an invalid field type returns an empty array.
155+
['entity_reference_revisions', [
156+
'field' => 'title',
157+
'access' => TRUE,
158+
'access_operation' => 'view',
159+
],
160+
],
161+
// Same test set for the entity_reference_layout_revisions data producer.
162+
// Test that an empty reference field returns an empty array.
163+
['entity_reference_layout_revisions', [
164+
'field' => 'field_test1_to_test2',
165+
'access' => TRUE,
166+
'access_operation' => 'view',
167+
],
168+
],
169+
// Test that an invalid field name returns an empty array.
170+
['entity_reference_layout_revisions', [
171+
'field' => 'does_not_exist',
172+
'access' => TRUE,
173+
'access_operation' => 'view',
174+
],
175+
],
176+
// Test that an invalid field type returns an empty array.
177+
['entity_reference_layout_revisions', [
178+
'field' => 'title',
179+
'access' => TRUE,
180+
'access_operation' => 'view',
181+
],
182+
],
183+
];
184+
}
185+
95186
}

0 commit comments

Comments
 (0)