vendor/webonyx/graphql-php/src/Executor/Executor.php line 142

  1. <?php declare(strict_types=1);
  2. namespace GraphQL\Executor;
  3. use GraphQL\Error\InvariantViolation;
  4. use GraphQL\Executor\Promise\Adapter\SyncPromiseAdapter;
  5. use GraphQL\Executor\Promise\Promise;
  6. use GraphQL\Executor\Promise\PromiseAdapter;
  7. use GraphQL\Language\AST\DocumentNode;
  8. use GraphQL\Type\Definition\ResolveInfo;
  9. use GraphQL\Type\Schema;
  10. use GraphQL\Utils\Utils;
  11. /**
  12.  * Implements the "Evaluating requests" section of the GraphQL specification.
  13.  *
  14.  * @phpstan-type FieldResolver callable(mixed, array<string, mixed>, mixed, ResolveInfo): mixed
  15.  * @phpstan-type ImplementationFactory callable(PromiseAdapter, Schema, DocumentNode, mixed, mixed, array<mixed>, ?string, callable): ExecutorImplementation
  16.  */
  17. class Executor
  18. {
  19.     /**
  20.      * @var callable
  21.      *
  22.      * @phpstan-var FieldResolver
  23.      */
  24.     private static $defaultFieldResolver = [self::class, 'defaultFieldResolver'];
  25.     private static ?PromiseAdapter $defaultPromiseAdapter;
  26.     /**
  27.      * @var callable
  28.      *
  29.      * @phpstan-var ImplementationFactory
  30.      */
  31.     private static $implementationFactory = [ReferenceExecutor::class, 'create'];
  32.     /**
  33.      * @phpstan-return FieldResolver
  34.      */
  35.     public static function getDefaultFieldResolver(): callable
  36.     {
  37.         return self::$defaultFieldResolver;
  38.     }
  39.     /**
  40.      * Set a custom default resolve function.
  41.      *
  42.      * @phpstan-param FieldResolver $fieldResolver
  43.      */
  44.     public static function setDefaultFieldResolver(callable $fieldResolver): void
  45.     {
  46.         self::$defaultFieldResolver $fieldResolver;
  47.     }
  48.     public static function getPromiseAdapter(): PromiseAdapter
  49.     {
  50.         return self::$defaultPromiseAdapter ??= new SyncPromiseAdapter();
  51.     }
  52.     /**
  53.      * Set a custom default promise adapter.
  54.      */
  55.     public static function setPromiseAdapter(?PromiseAdapter $defaultPromiseAdapter null): void
  56.     {
  57.         self::$defaultPromiseAdapter $defaultPromiseAdapter;
  58.     }
  59.     /**
  60.      * @phpstan-return ImplementationFactory
  61.      */
  62.     public static function getImplementationFactory(): callable
  63.     {
  64.         return self::$implementationFactory;
  65.     }
  66.     /**
  67.      * Set a custom executor implementation factory.
  68.      *
  69.      * @phpstan-param ImplementationFactory $implementationFactory
  70.      */
  71.     public static function setImplementationFactory(callable $implementationFactory): void
  72.     {
  73.         self::$implementationFactory $implementationFactory;
  74.     }
  75.     /**
  76.      * Executes DocumentNode against given $schema.
  77.      *
  78.      * Always returns ExecutionResult and never throws.
  79.      * All errors which occur during operation execution are collected in `$result->errors`.
  80.      *
  81.      * @param mixed                     $rootValue
  82.      * @param mixed                     $contextValue
  83.      * @param array<string, mixed>|null $variableValues
  84.      *
  85.      * @phpstan-param FieldResolver|null $fieldResolver
  86.      *
  87.      * @api
  88.      *
  89.      * @throws InvariantViolation
  90.      */
  91.     public static function execute(
  92.         Schema $schema,
  93.         DocumentNode $documentNode,
  94.         $rootValue null,
  95.         $contextValue null,
  96.         ?array $variableValues null,
  97.         ?string $operationName null,
  98.         ?callable $fieldResolver null
  99.     ): ExecutionResult {
  100.         $promiseAdapter = new SyncPromiseAdapter();
  101.         $result = static::promiseToExecute(
  102.             $promiseAdapter,
  103.             $schema,
  104.             $documentNode,
  105.             $rootValue,
  106.             $contextValue,
  107.             $variableValues,
  108.             $operationName,
  109.             $fieldResolver
  110.         );
  111.         return $promiseAdapter->wait($result);
  112.     }
  113.     /**
  114.      * Same as execute(), but requires promise adapter and returns a promise which is always
  115.      * fulfilled with an instance of ExecutionResult and never rejected.
  116.      *
  117.      * Useful for async PHP platforms.
  118.      *
  119.      * @param mixed                     $rootValue
  120.      * @param mixed                     $contextValue
  121.      * @param array<string, mixed>|null $variableValues
  122.      *
  123.      * @phpstan-param FieldResolver|null $fieldResolver
  124.      *
  125.      * @api
  126.      */
  127.     public static function promiseToExecute(
  128.         PromiseAdapter $promiseAdapter,
  129.         Schema $schema,
  130.         DocumentNode $documentNode,
  131.         $rootValue null,
  132.         $contextValue null,
  133.         ?array $variableValues null,
  134.         ?string $operationName null,
  135.         ?callable $fieldResolver null
  136.     ): Promise {
  137.         $executor = (self::$implementationFactory)(
  138.             $promiseAdapter,
  139.             $schema,
  140.             $documentNode,
  141.             $rootValue,
  142.             $contextValue,
  143.             $variableValues ?? [],
  144.             $operationName,
  145.             $fieldResolver ?? self::$defaultFieldResolver
  146.         );
  147.         return $executor->doExecute();
  148.     }
  149.     /**
  150.      * If a resolve function is not given, then a default resolve behavior is used
  151.      * which takes the property of the root value of the same name as the field
  152.      * and returns it as the result, or if it's a function, returns the result
  153.      * of calling that function while passing along args and context.
  154.      *
  155.      * @param mixed $objectLikeValue
  156.      * @param array<string, mixed> $args
  157.      * @param mixed $contextValue
  158.      *
  159.      * @return mixed
  160.      */
  161.     public static function defaultFieldResolver($objectLikeValue, array $args$contextValueResolveInfo $info)
  162.     {
  163.         $property Utils::extractKey($objectLikeValue$info->fieldName);
  164.         return $property instanceof \Closure
  165.             $property($objectLikeValue$args$contextValue$info)
  166.             : $property;
  167.     }
  168. }