-
Notifications
You must be signed in to change notification settings - Fork 17
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
thunder rout entity data provider #707
base: 6.5.x
Are you sure you want to change the base?
Changes from 6 commits
a299eed
6322fce
8d8990d
0a313fc
3659fbf
311f5a2
e973276
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -164,6 +164,33 @@ Then we add the $path variable with a json string like this: | |
This variable can be added in the GraphQL explorer in the corresponding input field. All following examples will assume | ||
a variable definition like this. | ||
|
||
#### Requesting revisions | ||
|
||
Given a user has the permission to access revisions of content, the $path can contain revision routes as well. | ||
Revision routes are always internal drupal routes. | ||
If /example-page is Node 6 in Drupal, the following variables are valid: | ||
|
||
Get the current revision, which is the default query to the currently published page. | ||
```json | ||
{ | ||
"path": "/example-page" | ||
} | ||
``` | ||
|
||
Get a specific revision, can be an old revision, or a not yet published draft | ||
```json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [markdownlint] reported by reviewdog 🐶 |
||
{ | ||
"path": "/node/6/revision/11/view" | ||
} | ||
``` | ||
|
||
Get the latest revision, which might be an unpublished draft. The latest revision might not be available for a given node. | ||
```json | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [markdownlint] reported by reviewdog 🐶 |
||
{ | ||
"path": "/node/6/latest" | ||
} | ||
``` | ||
|
||
#### Paragraphs example | ||
|
||
Articles and taxonomy terms contain paragraph fields in Thunder, the following example shows how to request paragraphs' | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,164 @@ | ||
<?php | ||
|
||
namespace Drupal\thunder_gqls\Plugin\GraphQL\DataProducer; | ||
|
||
use Drupal\Core\Entity\EntityTypeManagerInterface; | ||
use Drupal\Core\Entity\RevisionableStorageInterface; | ||
use Drupal\Core\Entity\TranslatableInterface; | ||
use Drupal\Core\Plugin\ContainerFactoryPluginInterface; | ||
use Drupal\Core\Url; | ||
use Drupal\graphql\GraphQL\Buffers\EntityBuffer; | ||
use Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer; | ||
use Drupal\graphql\GraphQL\Execution\FieldContext; | ||
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase; | ||
use GraphQL\Deferred; | ||
use Symfony\Component\DependencyInjection\ContainerInterface; | ||
|
||
/** | ||
* Loads the entity associated with the current URL. | ||
* | ||
* @DataProducer( | ||
* id = "thunder_route_entity", | ||
* name = @Translation("Load entity by uuid"), | ||
* description = @Translation("The entity belonging to the current url."), | ||
* produces = @ContextDefinition("entity", | ||
* label = @Translation("Entity") | ||
* ), | ||
* consumes = { | ||
* "url" = @ContextDefinition("any", | ||
* label = @Translation("The URL") | ||
* ), | ||
* "language" = @ContextDefinition("string", | ||
* label = @Translation("Language"), | ||
* required = FALSE | ||
* ) | ||
* } | ||
* ) | ||
*/ | ||
class ThunderRouteEntity extends DataProducerPluginBase implements ContainerFactoryPluginInterface { | ||
|
||
/** | ||
* The entity type manager. | ||
* | ||
* @var \Drupal\Core\Entity\EntityTypeManagerInterface | ||
*/ | ||
protected $entityTypeManager; | ||
|
||
/** | ||
* The entity buffer service. | ||
* | ||
* @var \Drupal\graphql\GraphQL\Buffers\EntityBuffer | ||
*/ | ||
protected $entityBuffer; | ||
|
||
/** | ||
* The entity buffer service. | ||
* | ||
* @var \Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer | ||
*/ | ||
protected $entityRevisionBuffer; | ||
|
||
/** | ||
* {@inheritdoc} | ||
*/ | ||
public static function create(ContainerInterface $container, array $configuration, $pluginId, $pluginDefinition) { | ||
return new static( | ||
$configuration, | ||
$pluginId, | ||
$pluginDefinition, | ||
$container->get('entity_type.manager'), | ||
$container->get('graphql.buffer.entity'), | ||
$container->get('graphql.buffer.entity_revision') | ||
); | ||
} | ||
|
||
/** | ||
* RouteEntity constructor. | ||
* | ||
* @param array $configuration | ||
* The plugin configuration array. | ||
* @param string $pluginId | ||
* The plugin id. | ||
* @param mixed $pluginDefinition | ||
* The plugin definition array. | ||
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entityTypeManager | ||
* The language manager service. | ||
* @param \Drupal\graphql\GraphQL\Buffers\EntityBuffer $entityBuffer | ||
* The entity buffer service. | ||
* @param \Drupal\graphql\GraphQL\Buffers\EntityRevisionBuffer $entityRevisionBuffer | ||
* The entity revision buffer service. | ||
* | ||
* @codeCoverageIgnore | ||
*/ | ||
public function __construct( | ||
array $configuration, | ||
$pluginId, | ||
$pluginDefinition, | ||
EntityTypeManagerInterface $entityTypeManager, | ||
EntityBuffer $entityBuffer, | ||
EntityRevisionBuffer $entityRevisionBuffer | ||
) { | ||
parent::__construct($configuration, $pluginId, $pluginDefinition); | ||
$this->entityTypeManager = $entityTypeManager; | ||
$this->entityBuffer = $entityBuffer; | ||
$this->entityRevisionBuffer = $entityRevisionBuffer; | ||
} | ||
|
||
/** | ||
* Resolver. | ||
* | ||
* @param \Drupal\Core\Url|mixed $url | ||
* The URL to get the route entity from. | ||
* @param string|null $language | ||
* The language code to get a translation of the entity. | ||
* @param \Drupal\graphql\GraphQL\Execution\FieldContext $context | ||
* The GraphQL field context. | ||
*/ | ||
public function resolve($url, ?string $language, FieldContext $context): ?Deferred { | ||
if (!$url instanceof Url) { | ||
return NULL; | ||
} | ||
|
||
[, $type, $subType] = explode('.', $url->getRouteName()); | ||
$parameters = $url->getRouteParameters(); | ||
$storage = $this->entityTypeManager->getStorage($type); | ||
|
||
if ($subType === 'latest_version' && $storage instanceof RevisionableStorageInterface) { | ||
$id = $storage->getLatestRevisionId($parameters[$type]); | ||
$resolver = $this->entityRevisionBuffer->add($type, $id); | ||
} | ||
elseif ($subType === 'revision') { | ||
$resolver = $this->entityRevisionBuffer->add($type, $parameters[$type . '_revision']); | ||
} | ||
else { | ||
$resolver = $this->entityBuffer->add($type, $parameters[$type]); | ||
} | ||
|
||
return new Deferred(function () use ($type, $resolver, $context, $language) { | ||
if (!$entity = $resolver()) { | ||
// If there is no entity with this id, add the list cache tags so that | ||
// the cache entry is purged whenever a new entity of this type is | ||
// saved. | ||
$type = $this->entityTypeManager->getDefinition($type); | ||
/** @var \Drupal\Core\Entity\EntityTypeInterface $type */ | ||
$tags = $type->getListCacheTags(); | ||
$context->addCacheTags($tags)->addCacheTags(['4xx-response']); | ||
return NULL; | ||
} | ||
|
||
// Get the correct translation. | ||
if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) { | ||
$entity = $entity->getTranslation($language); | ||
$entity->addCacheContexts(["static:language:{$language}"]); | ||
} | ||
|
||
$access = $entity->access('view', NULL, TRUE); | ||
$context->addCacheableDependency($access); | ||
if ($access->isAllowed()) { | ||
return $entity; | ||
} | ||
return NULL; | ||
}); | ||
} | ||
|
||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[markdownlint] reported by reviewdog 🐶
MD031/blanks-around-fences Fenced code blocks should be surrounded by blank lines [Context: "```json"]