Skip to content

Commit a087079

Browse files
blazeyofubhy
authored andcommitted
#343 Exposing base fields. (#376)
1 parent 556b4dd commit a087079

11 files changed

Lines changed: 189 additions & 47 deletions

File tree

modules/graphql_core/graphql_core.services.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
services:
22
graphql_core.type_mapper:
33
class: Drupal\graphql_core\TypeMapper
4-
arguments: ['%graphql_core.type_map%']
4+
arguments: ['@entity_type.manager', '%graphql_core.type_map%']
55

66
parameters:
77
graphql_core.type_map:

modules/graphql_core/src/Plugin/Deriver/EntityFieldDeriver.php

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -2,26 +2,38 @@
22

33
namespace Drupal\graphql_core\Plugin\Deriver;
44

5+
use Drupal\Core\Field\BaseFieldDefinition;
56
use Drupal\Core\Field\FieldStorageDefinitionInterface;
67
use Drupal\graphql\Utility\StringHelper;
7-
use Drupal\graphql_core\Plugin\Deriver\EntityFieldDeriverBase;
88
use Drupal\graphql_core\Plugin\GraphQL\Fields\EntityField;
99
use Drupal\graphql_core\Plugin\GraphQL\Types\EntityFieldType;
1010

11+
// TODO Reduce single-property fields to scalars.
12+
13+
// TODO Convert timestamps to strings?
14+
1115
/**
1216
* Deriver for RawValue fields.
1317
*/
1418
class EntityFieldDeriver extends EntityFieldDeriverBase {
1519

1620
/**
17-
* Provide plugin definition values from config field storage.
18-
*
19-
* @param string $entityTypeId
20-
* The host entity type.
21-
* @param string $bundleId
22-
* The host entity bundle.
23-
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $storage
24-
* Field storage definition object.
21+
* {@inheritdoc}
22+
*/
23+
protected function getBaseFieldDefinition($entityTypeId, BaseFieldDefinition $baseFieldDefinition, array $basePluginDefinition) {
24+
$fieldName = $baseFieldDefinition->getName();
25+
26+
$this->derivatives["$entityTypeId-$fieldName"] = [
27+
'types' => [StringHelper::camelCase([$entityTypeId])],
28+
'name' => EntityField::getId($fieldName),
29+
'multi' => $baseFieldDefinition->isMultiple(),
30+
'field' => $fieldName,
31+
'type' => EntityFieldType::getId($entityTypeId, $fieldName),
32+
] + $basePluginDefinition;
33+
}
34+
35+
/**
36+
* {@inheritdoc}
2537
*/
2638
protected function getConfigFieldDefinition($entityTypeId, $bundleId, FieldStorageDefinitionInterface $storage, array $basePluginDefinition) {
2739
$fieldName = $storage->getName();

modules/graphql_core/src/Plugin/Deriver/EntityFieldDeriverBase.php

Lines changed: 22 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,10 @@
66
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
77
use Drupal\Core\Entity\EntityTypeManagerInterface;
88
use Drupal\Core\Entity\FieldableEntityInterface;
9+
use Drupal\Core\Field\BaseFieldDefinition;
910
use Drupal\Core\Field\FieldStorageDefinitionInterface;
1011
use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface;
1112
use Drupal\Core\Entity\EntityFieldManagerInterface;
12-
use Drupal\graphql\Utility\StringHelper;
13-
use Drupal\graphql_content\ContentEntitySchemaConfig;
1413
use Symfony\Component\DependencyInjection\ContainerInterface;
1514

1615
/**
@@ -19,7 +18,19 @@
1918
abstract class EntityFieldDeriverBase extends DeriverBase implements ContainerDeriverInterface {
2019

2120
/**
22-
* Provide plugin definition values from config field storage.
21+
* Provides plugin definition values from base fields.
22+
*
23+
* @param string $entityTypeId
24+
* The host entity type.
25+
* @param \Drupal\Core\Field\BaseFieldDefinition $baseFieldDefinition
26+
* Base field definition object.
27+
* @param array $basePluginDefinition
28+
* Base definition array.
29+
*/
30+
protected function getBaseFieldDefinition($entityTypeId, BaseFieldDefinition $baseFieldDefinition, array $basePluginDefinition) {}
31+
32+
/**
33+
* Provides plugin definition values from config field storage.
2334
*
2435
* @param string $entityTypeId
2536
* The host entity type.
@@ -30,7 +41,7 @@ abstract class EntityFieldDeriverBase extends DeriverBase implements ContainerDe
3041
* @param array $basePluginDefinition
3142
* Base definition array.
3243
*/
33-
protected abstract function getConfigFieldDefinition($entityTypeId, $bundleId, FieldStorageDefinitionInterface $storage, array $basePluginDefinition);
44+
protected function getConfigFieldDefinition($entityTypeId, $bundleId, FieldStorageDefinitionInterface $storage, array $basePluginDefinition) {}
3445

3546
/**
3647
* The entity type manager.
@@ -68,18 +79,19 @@ public static function create(ContainerInterface $container, $basePluginId) {
6879
$container->get('entity_type.manager'),
6980
$container->get('entity_field.manager'),
7081
$container->get('entity_type.bundle.info'),
71-
$basePluginId);
82+
$basePluginId
83+
);
7284
}
7385

7486
/**
75-
* AbstractFieldFormatterDeriver constructor.
87+
* RawValueFieldItemDeriver constructor.
7688
*
7789
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
7890
* The entity type manager.
7991
* @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager
8092
* The entity field manager.
8193
* @param \Drupal\Core\Entity\EntityTypeBundleInfoInterface $entityTypeBundleInfo
82-
* The entity bundle info service.
94+
* The bundle info service.
8395
* @param string $basePluginId
8496
* The base plugin id.
8597
*/
@@ -110,7 +122,9 @@ public function getDerivativeDefinitions($basePluginDefinition) {
110122
continue;
111123
}
112124

113-
// TODO Add base fields.
125+
foreach ($this->entityFieldManager->getBaseFieldDefinitions($entityTypeId) as $baseFieldDefinition) {
126+
$this->getBaseFieldDefinition($entityTypeId, $baseFieldDefinition, $basePluginDefinition);
127+
}
114128

115129
foreach ($bundleInfo->getBundleInfo($entityTypeId) as $bundleId => $bundle) {
116130
foreach ($this->entityFieldManager->getFieldDefinitions($entityTypeId, $bundleId) as $fieldDefinition) {

modules/graphql_core/src/Plugin/Deriver/EntityFieldItemDeriver.php

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,11 @@
55
use Drupal\Core\Entity\EntityFieldManagerInterface;
66
use Drupal\Core\Entity\EntityTypeBundleInfoInterface;
77
use Drupal\Core\Entity\EntityTypeManagerInterface;
8+
use Drupal\Core\Field\BaseFieldDefinition;
89
use Drupal\Core\Field\FieldStorageDefinitionInterface;
910
use Drupal\graphql\Utility\StringHelper;
10-
use Drupal\graphql_core\Plugin\Deriver\EntityFieldDeriverBase;
11-
use Drupal\graphql_core\TypeMapper;
1211
use Drupal\graphql_core\Plugin\GraphQL\Types\EntityFieldType;
12+
use Drupal\graphql_core\TypeMapper;
1313
use Symfony\Component\DependencyInjection\ContainerInterface;
1414

1515
class EntityFieldItemDeriver extends EntityFieldDeriverBase {
@@ -59,15 +59,35 @@ public function __construct(
5959
$this->typeMapper = $typeMapper;
6060
}
6161

62+
/**
63+
* {@inheritdoc}
64+
*/
65+
protected function getBaseFieldDefinition($entityTypeId, BaseFieldDefinition $baseFieldDefinition, array $basePluginDefinition) {
66+
$this->getDerivativesFromPropertyDefinitions($entityTypeId, $baseFieldDefinition, $basePluginDefinition);
67+
}
6268

6369
/**
6470
* {@inheritdoc}
6571
*/
6672
protected function getConfigFieldDefinition($entityTypeId, $bundleId, FieldStorageDefinitionInterface $storage, array $basePluginDefinition) {
67-
$fieldName = $storage->getName();
73+
$this->getDerivativesFromPropertyDefinitions($entityTypeId, $storage, $basePluginDefinition);
74+
}
75+
76+
/**
77+
* Provide plugin definition values from base fields.
78+
*
79+
* @param string $entityTypeId
80+
* The host entity type.
81+
* @param \Drupal\Core\Field\FieldStorageDefinitionInterface $definition
82+
* Field definition object.
83+
* @param array $basePluginDefinition
84+
* Base plugin definition array.
85+
*/
86+
protected function getDerivativesFromPropertyDefinitions($entityTypeId, FieldStorageDefinitionInterface $definition, array $basePluginDefinition) {
87+
$fieldName = $definition->getName();
6888
$dataType = EntityFieldType::getId($entityTypeId, $fieldName);
6989

70-
foreach ($storage->getPropertyDefinitions() as $property => $definition) {
90+
foreach ($definition->getPropertyDefinitions() as $property => $definition) {
7191
if ($definition->getDataType() == 'map') {
7292
// TODO Is it possible to get the keys of a map (eg. the options array for link field) here?
7393
continue;

modules/graphql_core/src/Plugin/Deriver/EntityFieldTypeDeriver.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,8 +2,11 @@
22

33
namespace Drupal\graphql_core\Plugin\Deriver;
44

5+
use Drupal\Core\Field\BaseFieldDefinition;
56
use Drupal\Core\Field\FieldStorageDefinitionInterface;
7+
use Drupal\graphql\Utility\StringHelper;
68
use Drupal\graphql_core\Plugin\Deriver\EntityFieldDeriverBase;
9+
use Drupal\graphql_core\Plugin\GraphQL\Interfaces\Entity;
710
use Drupal\graphql_core\Plugin\GraphQL\Types\EntityBundle;
811
use Drupal\graphql_core\Plugin\GraphQL\Types\EntityFieldType;
912

@@ -12,6 +15,20 @@
1215
*/
1316
class EntityFieldTypeDeriver extends EntityFieldDeriverBase {
1417

18+
/**
19+
* {@inheritdoc}
20+
*/
21+
protected function getBaseFieldDefinition($entityTypeId, BaseFieldDefinition $baseFieldDefinition, array $basePluginDefinition) {
22+
$fieldName = $baseFieldDefinition->getName();
23+
24+
$this->derivatives["$entityTypeId-$fieldName"] = [
25+
'name' => EntityFieldType::getId($entityTypeId, $fieldName),
26+
'entity_type' => $entityTypeId,
27+
'data_type' => "entity:$entityTypeId:$fieldName",
28+
'interfaces' => [Entity::getId($entityTypeId)],
29+
] + $basePluginDefinition;
30+
}
31+
1532
/**
1633
* {@inheritdoc}
1734
*/

modules/graphql_core/src/Plugin/GraphQL/Fields/EntityField.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ class EntityField extends FieldPluginBase {
2929
* @return string
3030
*/
3131
public static function getId($fieldName) {
32-
return StringHelper::propCase($fieldName);
32+
return StringHelper::propCase([$fieldName]);
3333
}
3434

3535
/**

modules/graphql_core/src/Plugin/GraphQL/Interfaces/Entity.php

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
namespace Drupal\graphql_core\Plugin\GraphQL\Interfaces;
44

55
use Drupal\graphql\Plugin\GraphQL\Interfaces\InterfacePluginBase;
6+
use Drupal\graphql\Utility\StringHelper;
67

78
/**
89
* Plugin for GraphQL interfaces derived from Drupal entity types.
@@ -15,4 +16,16 @@
1516
*/
1617
class Entity extends InterfacePluginBase {
1718

19+
/**
20+
* Returns name of the bundle.
21+
*
22+
* @param string $entityTypeId
23+
* The entity type.
24+
*
25+
* @return string
26+
*/
27+
public static function getId($entityTypeId) {
28+
return StringHelper::camelCase([$entityTypeId]);
29+
}
30+
1831
}

modules/graphql_core/src/Plugin/GraphQL/Types/EntityFieldType.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,8 @@ class EntityFieldType extends TypePluginBase {
2929
* The GraphQL type name.
3030
*/
3131
public static function getId($entityTypeId, $fieldName) {
32-
return StringHelper::camelCase([$entityTypeId, $fieldName, 'field']);
32+
$result = StringHelper::camelCase(['type', $entityTypeId, $fieldName]);
33+
return $result;
3334
}
3435

3536
}

modules/graphql_core/src/TypeMapper.php

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,25 @@
22

33
namespace Drupal\graphql_core;
44

5+
use Drupal\Core\Entity\ContentEntityType;
6+
use Drupal\Core\Entity\EntityTypeManagerInterface;
7+
use Drupal\Core\Entity\TypedData\EntityDataDefinition;
58
use Drupal\Core\TypedData\DataDefinitionInterface;
69
use Drupal\Core\TypedData\DataReferenceDefinitionInterface;
710
use Drupal\graphql\Utility\StringHelper;
811

12+
/**
13+
* GraphQL type mapper service.
14+
*/
915
class TypeMapper {
1016

17+
/**
18+
* Mapping of graphql types to drupal types.
19+
*
20+
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
21+
*/
22+
protected $entityTypeManager;
23+
1124
/**
1225
* Mapping of graphql types to drupal types.
1326
*
@@ -18,10 +31,13 @@ class TypeMapper {
1831
/**
1932
* TypeMapper constructor.
2033
*
34+
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager
35+
* The entity type manager service.
2136
* @param array $typeMap
2237
* The mapping of graphql types to drupal types.
2338
*/
24-
public function __construct(array $typeMap) {
39+
public function __construct(EntityTypeManagerInterface $entityTypeManager, array $typeMap) {
40+
$this->entityTypeManager = $entityTypeManager;
2541
$this->typeMap = $typeMap;
2642
}
2743

@@ -34,15 +50,22 @@ public function __construct(array $typeMap) {
3450
* @return string
3551
*/
3652
public function typedDataToGraphQLFieldType(DataDefinitionInterface $dataDefinition) {
53+
$dataType = $dataDefinition->getDataType();
3754
if ($dataDefinition instanceof DataReferenceDefinitionInterface) {
3855
$targetDefinition = $dataDefinition->getTargetDefinition();
39-
$entityType = $targetDefinition->getEntityTypeId();
56+
if ($targetDefinition instanceof EntityDataDefinition) {
57+
$entityType = $targetDefinition->getEntityTypeId();
58+
59+
if ($this->entityTypeManager->getDefinition($entityType) instanceof ContentEntityType) {
60+
return StringHelper::camelCase($entityType);
61+
}
4062

41-
return StringHelper::camelCase($entityType);
63+
// TODO Handle config entity references.
64+
}
4265
}
4366

4467
foreach ($this->typeMap as $graphQlType => $typedDataTypes) {
45-
if (in_array($dataDefinition->getDataType(), $typedDataTypes)) {
68+
if (in_array($dataType, $typedDataTypes)) {
4669
return $graphQlType;
4770
}
4871
}

modules/graphql_core/tests/queries/raw_field_values.gql

Lines changed: 31 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,39 @@ query ($path: String!) {
22
route:route(path: $path) {
33
entity {
44
... on NodeTest {
5-
body {
5+
nid {
6+
value
7+
}
8+
vid {
9+
value
10+
}
11+
langcode {
12+
value
13+
}
14+
type {
15+
targetId
16+
}
17+
title {
18+
value
19+
}
20+
status {
21+
value
22+
}
23+
promote {
24+
value
25+
}
26+
sticky {
627
value
28+
}
29+
revisionTranslationAffected {
30+
value
31+
}
32+
body {
33+
summaryProcessed
734
summary
35+
processed
36+
format
37+
value
838
}
939
fieldText {
1040
value
@@ -42,17 +72,11 @@ query ($path: String!) {
4272
}
4373
fieldFile {
4474
targetId
45-
entity {
46-
entityLabel
47-
}
4875
display
4976
description
5077
}
5178
fieldImage {
5279
targetId
53-
entity {
54-
entityLabel
55-
}
5680
alt
5781
title
5882
width

0 commit comments

Comments
 (0)