diff --git a/src/Plugin/GraphQL/DataProducer/Field/EntityReference.php b/src/Plugin/GraphQL/DataProducer/Field/EntityReference.php index 2d0a97410..0cd411b1d 100644 --- a/src/Plugin/GraphQL/DataProducer/Field/EntityReference.php +++ b/src/Plugin/GraphQL/DataProducer/Field/EntityReference.php @@ -6,7 +6,6 @@ use Drupal\Core\Entity\EntityRepositoryInterface; use Drupal\Core\Entity\EntityTypeManagerInterface; use Drupal\Core\Entity\FieldableEntityInterface; -use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; @@ -63,6 +62,8 @@ */ class EntityReference extends DataProducerPluginBase implements ContainerFactoryPluginInterface { + use EntityReferenceTrait; + /** * The entity type manager service. * @@ -161,41 +162,7 @@ public function resolve(EntityInterface $entity, $field, ?string $language, ?arr $resolver = $this->entityBuffer->add($type, $ids); return new Deferred(function () use ($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context) { - $entities = $resolver() ?: []; - $entities = array_filter($entities, function (EntityInterface $entity) use ($language, $bundles, $access, $accessOperation, $accessUser, $context) { - if (isset($bundles) && !in_array($entity->bundle(), $bundles)) { - return FALSE; - } - - // Get the correct translation. - if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) { - $entity = $entity->getTranslation($language); - $entity->addCacheContexts(["static:language:{$language}"]); - } - - // Check if the passed user (or current user if none is passed) has - // access to the entity, if not return NULL. - if ($access) { - /** @var \Drupal\Core\Access\AccessResultInterface $accessResult */ - $accessResult = $entity->access($accessOperation, $accessUser, TRUE); - $context->addCacheableDependency($accessResult); - if (!$accessResult->isAllowed()) { - return FALSE; - } - } - - return TRUE; - }); - - if (empty($entities)) { - $type = $this->entityTypeManager->getDefinition($type); - /** @var \Drupal\Core\Entity\EntityTypeInterface $type */ - $tags = $type->getListCacheTags(); - $context->addCacheTags($tags); - return NULL; - } - - return $entities; + return $this->getReferencedEntities($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context); }); } diff --git a/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceLayoutRevisions.php b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceLayoutRevisions.php index ddcc2ab06..2928bae60 100644 --- a/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceLayoutRevisions.php +++ b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceLayoutRevisions.php @@ -5,7 +5,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Entity\FieldableEntityInterface; -use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; @@ -36,7 +35,6 @@ * ), * "language" = @ContextDefinition("string", * label = @Translation("Language"), - * multiple = TRUE, * required = FALSE * ), * "bundle" = @ContextDefinition("string", @@ -64,6 +62,8 @@ */ class EntityReferenceLayoutRevisions extends DataProducerPluginBase implements ContainerFactoryPluginInterface { + use EntityReferenceTrait; + /** * The entity type manager service. * @@ -166,42 +166,7 @@ public function resolve(EntityInterface $entity, string $field, ?string $languag $resolver = $this->entityRevisionBuffer->add($type, $vids); return new Deferred(function () use ($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context) { - $entities = $resolver() ?: []; - - $entities = array_filter($entities, function (EntityInterface $entity) use ($language, $bundles, $access, $accessOperation, $accessUser, $context) { - if (isset($bundles) && !in_array($entity->bundle(), $bundles)) { - return FALSE; - } - - // Get the correct translation. - if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) { - $entity = $entity->getTranslation($language); - $entity->addCacheContexts(["static:language:{$language}"]); - } - - // Check if the passed user (or current user if none is passed) has - // access to the entity, if not return NULL. - if ($access) { - /** @var \Drupal\Core\Access\AccessResultInterface $accessResult */ - $accessResult = $entity->access($accessOperation, $accessUser, TRUE); - $context->addCacheableDependency($accessResult); - if (!$accessResult->isAllowed()) { - return FALSE; - } - } - - return TRUE; - }); - - if (empty($entities)) { - $type = $this->entityTypeManager->getDefinition($type); - /** @var \Drupal\Core\Entity\EntityTypeInterface $type */ - $tags = $type->getListCacheTags(); - $context->addCacheTags($tags); - return NULL; - } - - return $entities; + return $this->getReferencedEntities($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context); }); } diff --git a/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceRevisions.php b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceRevisions.php index 31a1d15a3..7dd09bfa5 100644 --- a/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceRevisions.php +++ b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceRevisions.php @@ -5,7 +5,6 @@ use Drupal\Core\Entity\EntityInterface; use Drupal\Core\Entity\EntityTypeManager; use Drupal\Core\Entity\FieldableEntityInterface; -use Drupal\Core\Entity\TranslatableInterface; use Drupal\Core\Field\EntityReferenceFieldItemListInterface; use Drupal\Core\Plugin\ContainerFactoryPluginInterface; use Drupal\Core\Session\AccountInterface; @@ -36,7 +35,6 @@ * ), * "language" = @ContextDefinition("string", * label = @Translation("Language"), - * multiple = TRUE, * required = FALSE * ), * "bundle" = @ContextDefinition("string", @@ -64,6 +62,8 @@ */ class EntityReferenceRevisions extends DataProducerPluginBase implements ContainerFactoryPluginInterface { + use EntityReferenceTrait; + /** * The entity type manager service. * @@ -166,42 +166,7 @@ public function resolve(EntityInterface $entity, string $field, ?string $languag $resolver = $this->entityRevisionBuffer->add($type, $vids); return new Deferred(function () use ($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context) { - $entities = $resolver() ?: []; - - $entities = array_filter($entities, function (EntityInterface $entity) use ($language, $bundles, $access, $accessOperation, $accessUser, $context) { - if (isset($bundles) && !in_array($entity->bundle(), $bundles)) { - return FALSE; - } - - // Get the correct translation. - if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) { - $entity = $entity->getTranslation($language); - $entity->addCacheContexts(["static:language:{$language}"]); - } - - // Check if the passed user (or current user if none is passed) has - // access to the entity, if not return NULL. - if ($access) { - /** @var \Drupal\Core\Access\AccessResultInterface $accessResult */ - $accessResult = $entity->access($accessOperation, $accessUser, TRUE); - $context->addCacheableDependency($accessResult); - if (!$accessResult->isAllowed()) { - return FALSE; - } - } - - return TRUE; - }); - - if (empty($entities)) { - $type = $this->entityTypeManager->getDefinition($type); - /** @var \Drupal\Core\Entity\EntityTypeInterface $type */ - $tags = $type->getListCacheTags(); - $context->addCacheTags($tags); - return NULL; - } - - return $entities; + return $this->getReferencedEntities($type, $language, $bundles, $access, $accessUser, $accessOperation, $resolver, $context); }); } diff --git a/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceTrait.php b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceTrait.php new file mode 100644 index 000000000..f004e2b87 --- /dev/null +++ b/src/Plugin/GraphQL/DataProducer/Field/EntityReferenceTrait.php @@ -0,0 +1,98 @@ +getTranslated($entities, $language); + $entities = $this->filterAccessible($entities, $bundles, $access, $accessUser, $accessOperation, $context); + + if (empty($entities)) { + $type = $this->entityTypeManager->getDefinition($type); + /** @var \Drupal\Core\Entity\EntityTypeInterface $type */ + $tags = $type->getListCacheTags(); + $context->addCacheTags($tags); + return NULL; + } + + return $entities; + } + + /** + * Get the referenced entities in the language of the referencer. + * + * @param array $entities + * @param string $language + * + * @return array + */ + private function getTranslated($entities, $language) { + if ($language) { + $entities = array_map(function (EntityInterface $entity) use ($language) { + if ($language !== $entity->language()->getId() && $entity instanceof TranslatableInterface && $entity->hasTranslation($language)) { + $entity = $entity->getTranslation($language); + } + + $entity->addCacheContexts(["static:language:{$language}"]); + return $entity; + }, $entities); + } + + return $entities; + } + + /** + * Filter out not accessible entities. + * + * @param array $entities + * @param array|null $bundles + * @param bool $access + * @param \Drupal\Core\Session\AccountInterface|NULL $accessUser + * @param string $accessOperation + * @param \Drupal\graphql\GraphQL\Execution\FieldContext $context + * + * @return array + */ + private function filterAccessible($entities, $bundles, $access, $accessUser, $accessOperation, $context) { + $entities = array_filter($entities, function (EntityInterface $entity) use ($bundles, $access, $accessOperation, $accessUser, $context) { + if (isset($bundles) && !in_array($entity->bundle(), $bundles)) { + return FALSE; + } + + // Check if the passed user (or current user if none is passed) has + // access to the entity, if not return NULL. + if ($access) { + /* @var $accessResult \Drupal\Core\Access\AccessResultInterface */ + $accessResult = $entity->access($accessOperation, $accessUser, TRUE); + $context->addCacheableDependency($accessResult); + if (!$accessResult->isAllowed()) { + return FALSE; + } + } + return TRUE; + }); + + return $entities; + } + +}