Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion graphql.module
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
<?php

use Drupal\Core\Cache\Cache;
use Drupal\Core\Url;
use Drupal\graphql\Utility\StringHelper;

Expand Down Expand Up @@ -63,7 +64,7 @@ function graphql_graphql_interfaces_alter(&$definitions) {
}, $definitions);

foreach ($interfaces as $index => $list) {
$definition['interfaces'] = $list;
$definitions[$index]['interfaces'] = $list;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function getDerivativeDefinitions($basePluginDefinition) {
continue;
}

$this->derivatives[$typeId] = [
$derivative = [
'name' => StringHelper::camelCase($typeId),
'description' => $this->t("The '@type' entity type.", [
'@type' => $type->getLabel(),
Expand All @@ -33,6 +33,13 @@ public function getDerivativeDefinitions($basePluginDefinition) {
'interfaces' => $this->getInterfaces($type, $basePluginDefinition),
'entity_type' => $typeId,
] + $basePluginDefinition;

if ($typeId === 'node') {
// TODO: Make this more generic somehow.
$derivative['response_cache_contexts'][] = 'user.node_grants:view';
}

$this->derivatives[$typeId] = $derivative;
}

return parent::getDerivativeDefinitions($basePluginDefinition);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ public function getDerivativeDefinitions($basePluginDefinition) {
}

foreach ($bundles[$typeId] as $bundle => $bundleDefinition) {
$this->derivatives[$typeId . '-' . $bundle] = [
$derivative = [
'name' => StringHelper::camelCase($typeId, $bundle),
'description' => $this->t("The '@bundle' bundle of the '@type' entity type.", [
'@bundle' => $bundleDefinition['label'],
Expand All @@ -84,6 +84,13 @@ public function getDerivativeDefinitions($basePluginDefinition) {
'entity_type' => $typeId,
'entity_bundle' => $bundle,
] + $basePluginDefinition;

if ($typeId === 'node') {
// TODO: Make this more generic somehow.
$derivative['response_cache_contexts'][] = 'user.node_grants:view';
}

$this->derivatives[$typeId . '-' . $bundle] = $derivative;
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public function getDerivativeDefinitions($basePluginDefinition) {
continue;
}

$this->derivatives[$typeId] = [
$derivative = [
'name' => StringHelper::camelCase($typeId),
'description' => $this->t("The '@type' entity type.", [
'@type' => $type->getLabel(),
Expand All @@ -34,6 +34,13 @@ public function getDerivativeDefinitions($basePluginDefinition) {
'interfaces' => $this->getInterfaces($type, $basePluginDefinition),
'entity_type' => $typeId,
] + $basePluginDefinition;

if ($typeId === 'node') {
// TODO: Make this more generic somehow.
$derivative['response_cache_contexts'][] = 'user.node_grants:view';
}

$this->derivatives[$typeId] = $derivative;
}

return parent::getDerivativeDefinitions($basePluginDefinition);
Expand Down
21 changes: 21 additions & 0 deletions src/Annotation/GraphQLAnnotationBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,27 @@ abstract class GraphQLAnnotationBase extends Plugin {
*/
public $schema_cache_max_age = CacheBackendInterface::CACHE_PERMANENT;

/**
* The cache contexts for caching the response.
*
* @var array
*/
public $response_cache_contexts = ['user.permissions'];

/**
* The cache tags for caching theresponse.
*
* @var array
*/
public $response_cache_tags = [];

/**
* The cache max age for caching the response.
*
* @var array
*/
public $response_cache_max_age = CacheBackendInterface::CACHE_PERMANENT;

/**
* GraphQLAnnotationBase constructor.
*
Expand Down
21 changes: 0 additions & 21 deletions src/Annotation/GraphQLField.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,25 +61,4 @@ class GraphQLField extends GraphQLAnnotationBase {
*/
public $deprecated = FALSE;

/**
* The cache contexts for caching the response.
*
* @var array
*/
public $response_cache_contexts = ['user.permissions'];

/**
* The cache tags for caching theresponse.
*
* @var array
*/
public $response_cache_tags = [];

/**
* The cache max age for caching the response.
*
* @var array
*/
public $response_cache_max_age = CacheBackendInterface::CACHE_PERMANENT;

}
32 changes: 31 additions & 1 deletion src/GraphQL/Visitors/CacheContextsCollector.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,10 @@

namespace Drupal\graphql\GraphQL\Visitors;

use Drupal\Core\Cache\Cache;
use GraphQL\Language\AST\FieldNode;
use GraphQL\Language\AST\NodeKind;
use GraphQL\Type\Definition\LeafType;
use GraphQL\Utils\TypeInfo;

class CacheContextsCollector {
Expand All @@ -17,10 +19,38 @@ public function getVisitor(TypeInfo $info, array &$contexts) {
'leave' => function (FieldNode $field) use ($info, &$contexts) {
$definition = $info->getFieldDef();
if (!empty($definition->config['contexts'])) {
$contexts = array_unique(array_merge($contexts, $definition->config['contexts']));
$contexts = Cache::mergeContexts($contexts, $this->collectCacheContexts($definition->config['contexts']));
}

$parent = $info->getParentType();
if (!empty($parent->config['contexts'])) {
$contexts = Cache::mergeContexts($contexts, $this->collectCacheContexts($parent->config['contexts']));
}

$type = $info->getType();
// Collect cache metadata from leaf types.
if ($type instanceof LeafType && !empty($type->config['contexts'])) {
$contexts = Cache::mergeContexts($contexts, $this->collectCacheContexts($type->config['contexts']));
}
},
],
];
}

/**
* Collects the cache contexts from a type or field config.
*
* @param array|callable $contexts
* The cache contexts array or a callable to return cache contexts.
*
* @return array
* The collected cache contexts.
*/
protected function collectCacheContexts($contexts) {
if (is_callable($contexts)) {
return $contexts();
}

return $contexts;
}
}
4 changes: 4 additions & 0 deletions src/Plugin/GraphQL/Enums/EnumPluginBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
namespace Drupal\graphql\Plugin\GraphQL\Enums;

use Drupal\Component\Plugin\PluginBase;
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\DescribablePluginTrait;
use Drupal\graphql\Plugin\SchemaBuilderInterface;
use Drupal\graphql\Plugin\TypePluginInterface;
use Drupal\graphql\Plugin\TypePluginManager;
use GraphQL\Type\Definition\EnumType;

abstract class EnumPluginBase extends PluginBase implements TypePluginInterface {
use CacheablePluginTrait;
use DescribablePluginTrait;

/**
Expand All @@ -20,6 +22,7 @@ public static function createInstance(SchemaBuilderInterface $builder, TypePlugi
'name' => $definition['name'],
'description' => $definition['description'],
'values' => $definition['values'],
'contexts' => $definition['contexts'],
]);
}

Expand All @@ -33,6 +36,7 @@ public function getDefinition() {
'name' => $definition['name'],
'description' => $this->buildDescription($definition),
'values' => $this->buildEnumValues($definition),
'contexts' => $this->buildCacheContexts($definition),
];
}

Expand Down
4 changes: 4 additions & 0 deletions src/Plugin/GraphQL/InputTypes/InputTypePluginBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Drupal\graphql\Plugin\GraphQL\InputTypes;

use Drupal\Component\Plugin\PluginBase;
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\DescribablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\TypedPluginTrait;
use Drupal\graphql\Plugin\SchemaBuilderInterface;
Expand All @@ -12,6 +13,7 @@
use GraphQL\Type\Definition\InputObjectType;

abstract class InputTypePluginBase extends PluginBase implements TypePluginInterface {
use CacheablePluginTrait;
use DescribablePluginTrait;
use TypedPluginTrait;

Expand All @@ -22,6 +24,7 @@ public static function createInstance(SchemaBuilderInterface $builder, TypePlugi
return new InputObjectType([
'name' => $definition['name'],
'description' => $definition['description'],
'contexts' => $definition['contexts'],
'fields' => function () use ($builder, $definition) {
return $builder->processArguments($definition['fields']);
},
Expand All @@ -38,6 +41,7 @@ public function getDefinition() {
'name' => $definition['name'],
'description' => $this->buildDescription($definition),
'fields' => $this->buildFields($definition),
'contexts' => $this->buildCacheContexts($definition),
];
}

Expand Down
18 changes: 18 additions & 0 deletions src/Plugin/GraphQL/Interfaces/InterfacePluginBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,16 @@
namespace Drupal\graphql\Plugin\GraphQL\Interfaces;

use Drupal\Component\Plugin\PluginBase;
use Drupal\Core\Cache\Cache;
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\DescribablePluginTrait;
use Drupal\graphql\Plugin\SchemaBuilderInterface;
use Drupal\graphql\Plugin\TypePluginInterface;
use Drupal\graphql\Plugin\TypePluginManager;
use GraphQL\Type\Definition\InterfaceType;

abstract class InterfacePluginBase extends PluginBase implements TypePluginInterface {
use CacheablePluginTrait;
use DescribablePluginTrait;

/**
Expand All @@ -19,6 +22,20 @@ public static function createInstance(SchemaBuilderInterface $builder, TypePlugi
return new InterfaceType([
'name' => $definition['name'],
'description' => $definition['description'],
'contexts' => function () use ($builder, $definition) {
$types = $builder->getSubTypes($definition['name']);

return array_reduce($types, function ($carry, $current) use ($builder) {
$type = $builder->getType($current);
if (!empty($type->config['contexts'])) {
$contexts = $type->config['contexts'];
$contexts = is_callable($contexts) ? $contexts() : $contexts;
return Cache::mergeContexts($carry, $contexts);
}

return $carry;
}, $definition['contexts']);
},
'fields' => function () use ($builder, $definition) {
$fields = $builder->getFields($definition['name']);

Expand Down Expand Up @@ -49,6 +66,7 @@ public function getDefinition() {
'name' => $definition['name'],
'description' => $this->buildDescription($definition),
'interfaces' => $this->buildInterfaces($definition),
'contexts' => $this->buildCacheContexts($definition),
];
}

Expand Down
4 changes: 4 additions & 0 deletions src/Plugin/GraphQL/Scalars/ScalarPluginBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,15 @@
namespace Drupal\graphql\Plugin\GraphQL\Scalars;

use Drupal\Component\Plugin\PluginBase;
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\DescribablePluginTrait;
use Drupal\graphql\Plugin\SchemaBuilderInterface;
use Drupal\graphql\Plugin\TypePluginInterface;
use Drupal\graphql\Plugin\TypePluginManager;
use GraphQL\Type\Definition\CustomScalarType;

abstract class ScalarPluginBase extends PluginBase implements TypePluginInterface {
use CacheablePluginTrait;
use DescribablePluginTrait;

/**
Expand All @@ -25,6 +27,7 @@ public static function createInstance(SchemaBuilderInterface $builder, TypePlugi
return new CustomScalarType([
'name' => $definition['name'],
'description' => $definition['description'],
'contexts' => $definition['contexts'],
'serialize' => [$class, 'serialize'],
'parseValue' => [$class, 'parseValue'],
'parseLiteral' => [$class, 'parseLiteral'],
Expand All @@ -40,6 +43,7 @@ public function getDefinition() {
return [
'name' => $definition['name'],
'description' => $this->buildDescription($definition),
'contexts' => $this->buildCacheContexts($definition),
];
}

Expand Down
4 changes: 4 additions & 0 deletions src/Plugin/GraphQL/Types/TypePluginBase.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use Drupal\Component\Plugin\PluginBase;
use Drupal\graphql\GraphQL\Execution\ResolveContext;
use Drupal\graphql\Plugin\GraphQL\Traits\CacheablePluginTrait;
use Drupal\graphql\Plugin\GraphQL\Traits\DescribablePluginTrait;
use Drupal\graphql\Plugin\SchemaBuilderInterface;
use Drupal\graphql\Plugin\TypePluginInterface;
Expand All @@ -13,6 +14,7 @@
use GraphQL\Type\Definition\ResolveInfo;

abstract class TypePluginBase extends PluginBase implements TypePluginInterface {
use CacheablePluginTrait;
use DescribablePluginTrait;

/**
Expand All @@ -22,6 +24,7 @@ public static function createInstance(SchemaBuilderInterface $builder, TypePlugi
return new ObjectType([
'name' => $definition['name'],
'description' => $definition['description'],
'contexts' => $definition['contexts'],
'fields' => function () use ($builder, $definition) {
$fields = $builder->getFields($definition['name']);

Expand Down Expand Up @@ -61,6 +64,7 @@ public function getDefinition() {
'description' => $this->buildDescription($definition),
'interfaces' => $this->buildInterfaces($definition),
'unions' => $this->buildUnions($definition),
'contexts' => $this->buildCacheContexts($definition),
'weight' => $definition['weight'],
];
}
Expand Down