-
Notifications
You must be signed in to change notification settings - Fork 201
/
Copy pathRouteEntity.php
147 lines (134 loc) · 4.48 KB
/
RouteEntity.php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
<?php
namespace Drupal\graphql\Plugin\GraphQL\DataProducer\Routing;
use Drupal\Core\DependencyInjection\DependencySerializationTrait;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Entity\TranslatableInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Url;
use Drupal\graphql\GraphQL\Buffers\EntityBuffer;
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 = "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 RouteEntity extends DataProducerPluginBase implements ContainerFactoryPluginInterface {
use DependencySerializationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The entity buffer service.
*
* @var \Drupal\graphql\GraphQL\Buffers\EntityBuffer
*/
protected $entityBuffer;
/**
* {@inheritdoc}
*
* @codeCoverageIgnore
*/
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')
);
}
/**
* 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.
*
* @codeCoverageIgnore
*/
public function __construct(
array $configuration,
$pluginId,
$pluginDefinition,
EntityTypeManagerInterface $entityTypeManager,
EntityBuffer $entityBuffer
) {
parent::__construct($configuration, $pluginId, $pluginDefinition);
$this->entityTypeManager = $entityTypeManager;
$this->entityBuffer = $entityBuffer;
}
/**
* 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) {
[, $type] = explode('.', $url->getRouteName());
$parameters = $url->getRouteParameters();
$id = $parameters[$type];
$resolver = $this->entityBuffer->add($type, $id);
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) {
if (!$entity->hasTranslation($language)) {
return NULL;
}
$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;
});
}
return NULL;
}
}