상속: extends AbstractAst, implements Youshido\GraphQL\Parser\Ast\Interfaces\FieldInterface
예제 #1
0
 /**
  * Coroutine to walk the query and schema in DFS manner (see AbstractQueryVisitor docs for more info) and yield a
  * tuple of (queryNode, schemaNode, childScore)
  *
  * childScore costs are accumulated via values sent into the coroutine.
  *
  * Most of the branching in this function is just to handle the different types in a query: Queries, Unions,
  * Fragments (anonymous and named), and Fields.  The core of the function is simple: recurse until we hit the base
  * case of a Field and yield that back up to the visitor up in `doVisit`.
  *
  * @param Query|Field|\Youshido\GraphQL\Parser\Ast\Interfaces\FragmentInterface $queryNode
  * @param FieldInterface                                                        $currentLevelAST
  *
  * @return \Generator
  */
 protected function walkQuery($queryNode, FieldInterface $currentLevelAST)
 {
     $childrenScore = 0;
     if (!$queryNode instanceof FieldAst) {
         foreach ($queryNode->getFields() as $queryField) {
             if ($queryField instanceof FragmentInterface) {
                 if ($queryField instanceof FragmentReference) {
                     $queryField = $this->executionContext->getRequest()->getFragment($queryField->getName());
                 }
                 // the next 7 lines are essentially equivalent to `yield from $this->walkQuery(...)` in PHP7.
                 // for backwards compatibility this is equivalent.
                 // This pattern is repeated multiple times in this function, and unfortunately cannot be extracted or
                 // made less verbose.
                 $gen = $this->walkQuery($queryField, $currentLevelAST);
                 $next = $gen->current();
                 while ($next) {
                     $received = (yield $next);
                     $childrenScore += (int) $received;
                     $next = $gen->send($received);
                 }
             } else {
                 $fieldType = $currentLevelAST->getType()->getNamedType();
                 if ($fieldType instanceof AbstractUnionType) {
                     foreach ($fieldType->getTypes() as $unionFieldType) {
                         if ($fieldAst = $unionFieldType->getField($queryField->getName())) {
                             $gen = $this->walkQuery($queryField, $fieldAst);
                             $next = $gen->current();
                             while ($next) {
                                 $received = (yield $next);
                                 $childrenScore += (int) $received;
                                 $next = $gen->send($received);
                             }
                         }
                     }
                 } elseif ($fieldType instanceof AbstractObjectType && ($fieldAst = $fieldType->getField($queryField->getName()))) {
                     $gen = $this->walkQuery($queryField, $fieldAst);
                     $next = $gen->current();
                     while ($next) {
                         $received = (yield $next);
                         $childrenScore += (int) $received;
                         $next = $gen->send($received);
                     }
                 }
             }
         }
     }
     // sanity check.  don't yield fragments; they don't contribute to cost
     if ($queryNode instanceof Query || $queryNode instanceof FieldAst) {
         // BASE CASE.  If we're here we're done recursing -
         // this node is either a field, or a query that we've finished recursing into.
         (yield [$queryNode, $currentLevelAST, $childrenScore]);
     }
 }
예제 #2
0
 protected function resolveQuery(AstQuery $query)
 {
     $schema = $this->executionContext->getSchema();
     $type = $query instanceof AstMutation ? $schema->getMutationType() : $schema->getQueryType();
     $field = new Field(['name' => $query instanceof AstMutation ? 'mutation' : 'query', 'type' => $type]);
     if (self::TYPE_NAME_QUERY == $query->getName()) {
         return [$this->getAlias($query) => $type->getName()];
     }
     $this->resolveValidator->assetTypeHasField($type, $query);
     $value = $this->resolveField($field, $query);
     return [$this->getAlias($query) => $value];
 }
예제 #3
0
 public function testQuery()
 {
     $arguments = [new Argument('limit', new Literal('10', new Location(1, 1)), new Location(1, 1))];
     $fields = [new Field('id', null, [], new Location(1, 1))];
     $query = new Query('ships', 'lastShips', $arguments, $fields, new Location(1, 1));
     $this->assertEquals('ships', $query->getName());
     $this->assertEquals('lastShips', $query->getAlias());
     $this->assertEquals($arguments, $query->getArguments());
     $this->assertEquals(['limit' => '10'], $query->getKeyValueArguments());
     $this->assertEquals($fields, $query->getFields());
     $this->assertTrue($query->hasArguments());
     $this->assertTrue($query->hasFields());
     $query->setFields([]);
     $query->setArguments([]);
     $this->assertEmpty($query->getArguments());
     $this->assertEmpty($query->getFields());
     $this->assertEmpty($query->getKeyValueArguments());
     $this->assertFalse($query->hasArguments());
     $this->assertFalse($query->hasFields());
     $query->addArgument(new Argument('offset', new Literal(10, new Location(1, 1)), new Location(1, 1)));
     $this->assertTrue($query->hasArguments());
 }