You are here

abstract class SdlSchemaPluginBase in GraphQL 8.4

Base class that can be used by schema plugins.

Hierarchy

Expanded class hierarchy of SdlSchemaPluginBase

2 files declare their use of SdlSchemaPluginBase
ExampleSchema.php in examples/graphql_example/src/Plugin/GraphQL/Schema/ExampleSchema.php
MockingTrait.php in tests/src/Traits/MockingTrait.php

File

src/Plugin/GraphQL/Schema/SdlSchemaPluginBase.php, line 27

Namespace

Drupal\graphql\Plugin\GraphQL\Schema
View source
abstract class SdlSchemaPluginBase extends PluginBase implements SchemaPluginInterface, ContainerFactoryPluginInterface, CacheableDependencyInterface {
  use RefinableCacheableDependencyTrait;

  /**
   * The cache bin for caching the parsed SDL.
   *
   * @var \Drupal\Core\Cache\CacheBackendInterface
   */
  protected $astCache;

  /**
   * Whether the system is currently in development mode.
   *
   * @var bool
   */
  protected $inDevelopment;

  /**
   * The schema extension plugin manager.
   *
   * @var \Drupal\graphql\Plugin\SchemaExtensionPluginManager
   */
  protected $extensionManager;

  /**
   * The module handler service.
   *
   * @var \Drupal\Core\Extension\ModuleHandlerInterface
   */
  protected $moduleHandler;

  /**
   * {@inheritdoc}
   *
   * @codeCoverageIgnore
   */
  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
    return new static($configuration, $plugin_id, $plugin_definition, $container
      ->get('cache.graphql.ast'), $container
      ->get('module_handler'), $container
      ->get('plugin.manager.graphql.schema_extension'), $container
      ->getParameter('graphql.config'));
  }

  /**
   * SdlSchemaPluginBase constructor.
   *
   * @param array $configuration
   *   The plugin configuration array.
   * @param string $pluginId
   *   The plugin id.
   * @param array $pluginDefinition
   *   The plugin definition array.
   * @param \Drupal\Core\Cache\CacheBackendInterface $astCache
   *   The cache bin for caching the parsed SDL.
   * @param \Drupal\Core\Extension\ModuleHandlerInterface $moduleHandler
   *   The module handler service.
   * @param \Drupal\graphql\Plugin\SchemaExtensionPluginManager $extensionManager
   *   The schema extension plugin manager.
   * @param array $config
   *   The service configuration.
   *
   * @codeCoverageIgnore
   */
  public function __construct(array $configuration, $pluginId, array $pluginDefinition, CacheBackendInterface $astCache, ModuleHandlerInterface $moduleHandler, SchemaExtensionPluginManager $extensionManager, array $config) {
    parent::__construct($configuration, $pluginId, $pluginDefinition);
    $this->inDevelopment = !empty($config['development']);
    $this->astCache = $astCache;
    $this->extensionManager = $extensionManager;
    $this->moduleHandler = $moduleHandler;
  }

  /**
   * {@inheritdoc}
   *
   * @throws \GraphQL\Error\SyntaxError
   * @throws \GraphQL\Error\Error
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   */
  public function getSchema(ResolverRegistryInterface $registry) {
    $extensions = $this
      ->getExtensions();
    $resolver = [
      $registry,
      'resolveType',
    ];
    $document = $this
      ->getSchemaDocument($extensions);
    $schema = BuildSchema::build($document, function ($config, TypeDefinitionNode $type) use ($resolver) {
      if ($type instanceof InterfaceTypeDefinitionNode || $type instanceof UnionTypeDefinitionNode) {
        $config['resolveType'] = $resolver;
      }
      return $config;
    });
    if (empty($extensions)) {
      return $schema;
    }
    foreach ($extensions as $extension) {
      $extension
        ->registerResolvers($registry);
    }
    if ($extendSchema = $this
      ->getExtensionDocument($extensions)) {
      return SchemaExtender::extend($schema, $extendSchema);
    }
    return $schema;
  }

  /**
   * @return \Drupal\graphql\Plugin\SchemaExtensionPluginInterface[]
   */
  protected function getExtensions() {
    return $this->extensionManager
      ->getExtensions($this
      ->getPluginId());
  }

  /**
   * Retrieves the parsed AST of the schema definition.
   *
   * @param array $extensions
   *
   * @return \GraphQL\Language\AST\DocumentNode
   *   The parsed schema document.
   *
   * @throws \GraphQL\Error\SyntaxError
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   */
  protected function getSchemaDocument(array $extensions = []) {

    // Only use caching of the parsed document if we aren't in development mode.
    $cid = "schema:{$this->getPluginId()}";
    if (empty($this->inDevelopment) && ($cache = $this->astCache
      ->get($cid))) {
      return $cache->data;
    }
    $extensions = array_filter(array_map(function (SchemaExtensionPluginInterface $extension) {
      return $extension
        ->getBaseDefinition();
    }, $extensions), function ($definition) {
      return !empty($definition);
    });
    $schema = array_merge([
      $this
        ->getSchemaDefinition(),
    ], $extensions);
    $ast = Parser::parse(implode("\n\n", $schema));
    if (empty($this->inDevelopment)) {
      $this->astCache
        ->set($cid, $ast, CacheBackendInterface::CACHE_PERMANENT, [
        'graphql',
      ]);
    }
    return $ast;
  }

  /**
   * Retrieves the parsed AST of the schema extension definitions.
   *
   * @param array $extensions
   *
   * @return \GraphQL\Language\AST\DocumentNode|null
   *   The parsed schema document.
   *
   * @throws \GraphQL\Error\SyntaxError
   */
  protected function getExtensionDocument(array $extensions = []) {

    // Only use caching of the parsed document if we aren't in development mode.
    $cid = "extension:{$this->getPluginId()}";
    if (empty($this->inDevelopment) && ($cache = $this->astCache
      ->get($cid))) {
      return $cache->data;
    }
    $extensions = array_filter(array_map(function (SchemaExtensionPluginInterface $extension) {
      return $extension
        ->getExtensionDefinition();
    }, $extensions), function ($definition) {
      return !empty($definition);
    });
    $ast = !empty($extensions) ? Parser::parse(implode("\n\n", $extensions)) : NULL;
    if (empty($this->inDevelopment)) {
      $this->astCache
        ->set($cid, $ast, CacheBackendInterface::CACHE_PERMANENT, [
        'graphql',
      ]);
    }
    return $ast;
  }

  /**
   * Retrieves the raw schema definition string.
   *
   * @return string
   *   The schema definition.
   *
   * @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
   */
  protected function getSchemaDefinition() {
    $id = $this
      ->getPluginId();
    $definition = $this
      ->getPluginDefinition();
    $module = $this->moduleHandler
      ->getModule($definition['provider']);
    $path = 'graphql/' . $id . '.graphqls';
    $file = $module
      ->getPath() . '/' . $path;
    if (!file_exists($file)) {
      throw new InvalidPluginDefinitionException($id, sprintf('The module "%s" needs to have a schema definition "%s" in its folder for "%s" to be valid.', $module
        ->getName(), $path, $definition['class']));
    }
    return file_get_contents($file) ?: NULL;
  }

}

Members

Namesort descending Modifiers Type Description Overrides
CacheableDependencyTrait::$cacheContexts protected property Cache contexts.
CacheableDependencyTrait::$cacheMaxAge protected property Cache max-age.
CacheableDependencyTrait::$cacheTags protected property Cache tags.
CacheableDependencyTrait::getCacheContexts public function 3
CacheableDependencyTrait::getCacheMaxAge public function 3
CacheableDependencyTrait::getCacheTags public function 3
CacheableDependencyTrait::setCacheability protected function Sets cacheability; useful for value object constructors.
PluginBase::$configuration protected property Configuration information passed into the plugin. 1
PluginBase::$pluginDefinition protected property The plugin implementation definition. 1
PluginBase::$pluginId protected property The plugin_id.
PluginBase::DERIVATIVE_SEPARATOR constant A string which is used to separate base plugin IDs from the derivative ID.
PluginBase::getBaseId public function Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface::getBaseId
PluginBase::getDerivativeId public function Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface::getDerivativeId
PluginBase::getPluginDefinition public function Gets the definition of the plugin implementation. Overrides PluginInspectionInterface::getPluginDefinition 3
PluginBase::getPluginId public function Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface::getPluginId
PluginBase::isConfigurable public function Determines if the plugin is configurable.
RefinableCacheableDependencyTrait::addCacheableDependency public function 1
RefinableCacheableDependencyTrait::addCacheContexts public function
RefinableCacheableDependencyTrait::addCacheTags public function
RefinableCacheableDependencyTrait::mergeCacheMaxAge public function
SchemaPluginInterface::getResolverRegistry public function Retrieves the resolver registry. 2
SdlSchemaPluginBase::$astCache protected property The cache bin for caching the parsed SDL.
SdlSchemaPluginBase::$extensionManager protected property The schema extension plugin manager.
SdlSchemaPluginBase::$inDevelopment protected property Whether the system is currently in development mode.
SdlSchemaPluginBase::$moduleHandler protected property The module handler service.
SdlSchemaPluginBase::create public static function @codeCoverageIgnore Overrides ContainerFactoryPluginInterface::create
SdlSchemaPluginBase::getExtensionDocument protected function Retrieves the parsed AST of the schema extension definitions.
SdlSchemaPluginBase::getExtensions protected function 1
SdlSchemaPluginBase::getSchema public function Overrides SchemaPluginInterface::getSchema
SdlSchemaPluginBase::getSchemaDefinition protected function Retrieves the raw schema definition string. 1
SdlSchemaPluginBase::getSchemaDocument protected function Retrieves the parsed AST of the schema definition.
SdlSchemaPluginBase::__construct public function SdlSchemaPluginBase constructor. Overrides PluginBase::__construct