From 46676df14403803c23aa9e4a49a97fed48a12a0a Mon Sep 17 00:00:00 2001 From: Sebastian Siemssen Date: Wed, 12 Sep 2018 13:00:31 +0200 Subject: [PATCH] Adding entity reference query functionality. --- .../Fields/EntityReferenceQueryDeriver.php | 116 ++++++++++++++++++ .../Fields/EntityReferenceReverseDeriver.php | 1 - .../Fields/EntityQuery/EntityQuery.php | 11 +- .../EntityReference/EntityReferenceQuery.php | 61 +++++++++ 4 files changed, 184 insertions(+), 5 deletions(-) create mode 100644 modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceQueryDeriver.php create mode 100644 modules/graphql_core/src/Plugin/GraphQL/Fields/EntityReference/EntityReferenceQuery.php diff --git a/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceQueryDeriver.php b/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceQueryDeriver.php new file mode 100644 index 000000000..a19465d45 --- /dev/null +++ b/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceQueryDeriver.php @@ -0,0 +1,116 @@ +get('entity_type.manager'), + $container->get('entity_field.manager'), + $container->get('typed_data_manager') + ); + } + + /** + * RawValueFieldItemDeriver constructor. + * + * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager + * The entity type manager. + * @param \Drupal\Core\Entity\EntityFieldManagerInterface $entityFieldManager + * The entity field manager. + * @param \Drupal\Core\TypedData\TypedDataManagerInterface $typedDataManager + * The typed data manager service. + */ + public function __construct( + EntityTypeManagerInterface $entityTypeManager, + EntityFieldManagerInterface $entityFieldManager, + TypedDataManagerInterface $typedDataManager + ) { + $this->entityTypeManager = $entityTypeManager; + $this->entityFieldManager = $entityFieldManager; + $this->typedDataManager = $typedDataManager; + } + + /** + * {@inheritdoc} + */ + public function getDerivativeDefinitions($basePluginDefinition) { + foreach ($this->entityTypeManager->getDefinitions() as $entityTypeId => $entityType) { + $interfaces = class_implements($entityType->getClass()); + if (!array_key_exists(FieldableEntityInterface::class, $interfaces)) { + continue; + } + + foreach ($this->entityFieldManager->getFieldStorageDefinitions($entityTypeId) as $fieldDefinition) { + if ($fieldDefinition->getType() !== 'entity_reference' || !$targetTypeId = $fieldDefinition->getSetting('target_type')) { + continue; + } + + $tags = array_merge($fieldDefinition->getCacheTags(), ['entity_field_info']); + $contexts = $fieldDefinition->getCacheContexts(); + $maxAge = $fieldDefinition->getCacheMaxAge(); + + $targetType = $this->entityTypeManager->getDefinition($targetTypeId); + $fieldName = $fieldDefinition->getName(); + $derivative = [ + 'parents' => [StringHelper::camelCase($entityTypeId)], + 'name' => StringHelper::propCase('query', $fieldName), + 'description' => $this->t('Query reference: @description', [ + '@description' => $fieldDefinition->getDescription(), + ]), + 'field' => $fieldName, + 'entity_key' => $targetType->getKey('id'), + 'entity_type' => $targetTypeId, + 'schema_cache_tags' => $tags, + 'schema_cache_contexts' => $contexts, + 'schema_cache_max_age' => $maxAge, + 'response_cache_tags' => $tags, + 'response_cache_contexts' => $contexts, + 'response_cache_max_age' => $maxAge, + ] + $basePluginDefinition; + + /** @var \Drupal\Core\Entity\TypedData\EntityDataDefinitionInterface $definition */ + $this->derivatives["$entityTypeId-$fieldName"] = $derivative; + } + } + + return $this->derivatives; + } +} diff --git a/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceReverseDeriver.php b/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceReverseDeriver.php index 2ed4c7941..da5b119f0 100644 --- a/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceReverseDeriver.php +++ b/modules/graphql_core/src/Plugin/Deriver/Fields/EntityReferenceReverseDeriver.php @@ -6,7 +6,6 @@ use Drupal\Core\Entity\EntityFieldManagerInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\FieldableEntityInterface; -use Drupal\Core\Field\BaseFieldDefinition; use Drupal\Core\Plugin\Discovery\ContainerDeriverInterface; use Drupal\Core\StringTranslation\StringTranslationTrait; use Drupal\Core\TypedData\TypedDataManagerInterface; diff --git a/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityQuery/EntityQuery.php b/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityQuery/EntityQuery.php index 270c4812a..4690637d2 100755 --- a/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityQuery/EntityQuery.php +++ b/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityQuery/EntityQuery.php @@ -18,7 +18,7 @@ * @GraphQLField( * id = "entity_query", * secure = true, - * type = "EntityQueryResult!", + * type = "EntityQueryResult", * arguments = { * "filter" = "EntityQueryFilterInput", * "sort" = "[EntityQuerySortInput]", @@ -138,11 +138,14 @@ protected function getEntityType($value, array $args, ResolveContext $context, R * @param \GraphQL\Type\Definition\ResolveInfo $info * The resolve info object. * - * @return \Drupal\Core\Entity\Query\QueryInterface + * @return \Drupal\Core\Entity\Query\QueryInterface|null * The entity query object. */ protected function getQuery($value, array $args, ResolveContext $context, ResolveInfo $info) { - $query = $this->getBaseQuery($value, $args, $context, $info); + if (!$query = $this->getBaseQuery($value, $args, $context, $info)) { + return NULL; + } + $query->range($args['offset'], $args['limit']); if (array_key_exists('revisions', $args)) { @@ -172,7 +175,7 @@ protected function getQuery($value, array $args, ResolveContext $context, Resolv * @param \GraphQL\Type\Definition\ResolveInfo $info * The resolve info object. * - * @return \Drupal\Core\Entity\Query\QueryInterface + * @return \Drupal\Core\Entity\Query\QueryInterface|null * The entity query object. */ protected function getBaseQuery($value, array $args, ResolveContext $context, ResolveInfo $info) { diff --git a/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityReference/EntityReferenceQuery.php b/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityReference/EntityReferenceQuery.php new file mode 100644 index 000000000..f5e735795 --- /dev/null +++ b/modules/graphql_core/src/Plugin/GraphQL/Fields/EntityReference/EntityReferenceQuery.php @@ -0,0 +1,61 @@ +getPluginDefinition(); + $key = $definition['entity_key']; + $field = $definition['field']; + $ids = array_map(function ($item) { + return $item['target_id']; + }, $value->get($field)->getValue()); + + if (empty($ids)) { + return NULL; + } + + $query->condition($key, $ids); + + return $query; + } + } + +}