Skip to content

Commit 15bb666

Browse files
authored
Allow static cache contexts. (#829)
1 parent 7536b39 commit 15bb666

10 files changed

Lines changed: 54 additions & 12 deletions

File tree

graphql.services.yml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,13 @@ services:
2424
parent: logger.channel_base
2525
arguments: ['graphql']
2626

27+
# Allows to statically define cache contexts.
28+
# TODO: This seems to be a missing feature in core.
29+
cache_context.static:
30+
class: Drupal\graphql\Cache\Context\StaticCacheContext
31+
tags:
32+
- { name: cache.context }
33+
2734
# Cache bin for the parsed sdl ast.
2835
cache.graphql.ast:
2936
class: Drupal\Core\Cache\CacheBackendInterface
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
<?php
2+
3+
namespace Drupal\graphql\Cache\Context;
4+
5+
use Drupal\Core\Cache\CacheableMetadata;
6+
use Drupal\Core\Cache\Context\CalculatedCacheContextInterface;
7+
8+
class StaticCacheContext implements CalculatedCacheContextInterface {
9+
10+
/**
11+
* {@inheritdoc}
12+
*/
13+
public static function getLabel() {
14+
return t('Static');
15+
}
16+
17+
/**
18+
* {@inheritdoc}
19+
*/
20+
public function getContext($parameter = NULL) {
21+
return $parameter ?: '';
22+
}
23+
24+
/**
25+
* {@inheritdoc}
26+
*/
27+
public function getCacheableMetadata($parameter = NULL) {
28+
return new CacheableMetadata();
29+
}
30+
31+
}

src/GraphQL/Execution/FieldContext.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ class FieldContext implements RefinableCacheableDependencyInterface {
2727
*/
2828
public function __construct(ResolveContext $context, ResolveInfo $info) {
2929
$this->addCacheContexts(['user.permissions']);
30-
3130
$this->context = $context;
3231
$this->info = $info;
3332
}

src/Plugin/GraphQL/DataProducer/Entity/EntityLoad.php

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -140,8 +140,9 @@ public function resolve($type, $id = NULL, $language = NULL, $bundles = NULL, Fi
140140
return NULL;
141141
}
142142

143-
if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) {
143+
if (isset($language) && $language !== $entity->language()->getId() && $entity instanceof TranslatableInterface) {
144144
$entity = $entity->getTranslation($language);
145+
$entity->addCacheContexts(["static:language:{$language}"]);
145146
}
146147

147148
return $entity;

src/Plugin/GraphQL/DataProducer/Entity/EntityLoadByUuid.php

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,10 @@
22

33
namespace Drupal\graphql\Plugin\GraphQL\DataProducer\Entity;
44

5-
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
65
use Drupal\Core\Entity\EntityRepositoryInterface;
76
use Drupal\Core\Entity\EntityTypeManager;
87
use Drupal\Core\Entity\TranslatableInterface;
98
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
10-
use Drupal\graphql\GraphQL\Buffers\EntityBuffer;
119
use Drupal\graphql\GraphQL\Buffers\EntityUuidBuffer;
1210
use Drupal\graphql\GraphQL\Execution\FieldContext;
1311
use Drupal\graphql\Plugin\GraphQL\DataProducer\DataProducerPluginBase;
@@ -144,6 +142,7 @@ public function resolve($type, $uuid, $language = NULL, $bundles = [], FieldCont
144142

145143
if (isset($language) && $language != $entity->language()->getId() && $entity instanceof TranslatableInterface) {
146144
$entity = $entity->getTranslation($language);
145+
$entity->addCacheContexts(["static:language:{$language}"]);
147146
}
148147

149148
return $entity;

src/Plugin/GraphQL/DataProducer/Entity/EntityLoadMultiple.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ public function resolve($type, array $ids, $language = NULL, array $bundles = NU
125125
$resolver = $this->entityBuffer->add($type, $ids);
126126

127127
return new Deferred(function () use ($type, $ids, $language, $bundles, $resolver, $context) {
128+
/** @var \Drupal\Core\Entity\EntityInterface[] $entities */
128129
if (!$entities = $resolver()) {
129130
// If there is no entity with this id, add the list cache tags so that the
130131
// cache entry is purged whenever a new entity of this type is saved.
@@ -137,16 +138,15 @@ public function resolve($type, array $ids, $language = NULL, array $bundles = NU
137138

138139
foreach ($entities as $id => $entity) {
139140
$context->addCacheableDependency($entities[$id]);
140-
141141
if (isset($bundles) && !in_array($entities[$id]->bundle(), $bundles)) {
142142
// If the entity is not among the allowed bundles, don't return it.
143143
unset($entities[$id]);
144144
continue;
145145
}
146146

147-
if (isset($language) && $language != $entities[$id]->language()
148-
->getId() && $entities[$id] instanceof TranslatableInterface) {
147+
if (isset($language) && $language !== $entities[$id]->language()->getId() && $entities[$id] instanceof TranslatableInterface) {
149148
$entities[$id] = $entities[$id]->getTranslation($language);
149+
$entities[$id]->addCacheContexts(["static:language:{$language}"]);
150150
}
151151

152152
$access = $entity->access('view', NULL, TRUE);

src/Plugin/GraphQL/DataProducer/Entity/EntityTranslation.php

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,9 @@ public function __construct(array $configuration, $pluginId, $pluginDefinition,
7979
*/
8080
public function resolve(EntityInterface $entity, $language) {
8181
if ($entity instanceof TranslatableInterface && $entity->isTranslatable()) {
82-
return $entity->getTranslation($language);
82+
$entity = $entity->getTranslation($language);
83+
$entity->addCacheContexts(["static:language:{$language}"]);
84+
return $entity;
8385
}
8486

8587
return NULL;

src/Plugin/GraphQL/DataProducer/Entity/EntityTranslations.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,10 @@ public function resolve(EntityInterface $entity) {
8181
$languages = $entity->getTranslationLanguages();
8282

8383
return array_map(function (LanguageInterface $language) use ($entity) {
84-
return $entity->getTranslation($language->getId());
84+
$langcode = $language->getId();
85+
$entity = $entity->getTranslation($langcode);
86+
$entity->addCacheContexts(["static:language:{$langcode}"]);
87+
return $entity;
8588
}, $languages);
8689
}
8790

src/Plugin/GraphQL/DataProducer/Field/EntityReference.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace Drupal\graphql\Plugin\GraphQL\DataProducer\Field;
44

5-
use Drupal\Core\Cache\RefinableCacheableDependencyInterface;
65
use Drupal\Core\Entity\EntityInterface;
76
use Drupal\Core\Entity\EntityRepositoryInterface;
87
use Drupal\Core\Entity\EntityTypeManager;
@@ -160,7 +159,9 @@ public function resolve(EntityInterface $entity, $field, $language = NULL, $bund
160159
if (isset($language)) {
161160
$entities = array_map(function (EntityInterface $entity) use ($language) {
162161
if ($language != $entity->language()->getId() && $entity instanceof TranslatableInterface) {
163-
return $entity->getTranslation($language);
162+
$entity = $entity->getTranslation($language);
163+
$entity->addCacheContexts(["static:language:{$language}"]);
164+
return $entity;
164165
}
165166

166167
return $entity;

tests/src/Traits/DataProducerExecutionTrait.php

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ protected function executeDataProducer($id, $contexts = []) {
3030
$context->addCacheContexts(Argument::any())->willReturn($context->reveal());
3131
$context->addCacheTags(Argument::any())->willReturn($context->reveal());
3232
$context->mergeCacheMaxAge(Argument::any())->willReturn($context->reveal());
33-
3433
$context->getContextValue(Argument::any(), Argument::any())->willReturn(NULL);
3534
$context->setContextValue(Argument::any(), Argument::any())->willReturn(FALSE);
3635
$context->hasContextValue(Argument::any())->willReturn(FALSE);

0 commit comments

Comments
 (0)