Inheritance: implements JsonSerializable
コード例 #1
0
ファイル: TestCase.php プロジェクト: rtuin/graphql-php
 /**
  * @return Schema
  */
 protected function getDefaultSchema()
 {
     $Being = new InterfaceType(['name' => 'Being', 'fields' => ['name' => ['type' => Type::string()]]]);
     $Pet = new InterfaceType(['name' => 'Pet', 'fields' => ['name' => ['type' => Type::string()]]]);
     $DogCommand = new EnumType(['name' => 'DogCommand', 'values' => ['SIT' => ['value' => 0], 'HEEL' => ['value' => 1], 'DOWN' => ['value' => 3]]]);
     $Dog = new ObjectType(['name' => 'Dog', 'fields' => ['name' => ['type' => Type::string()], 'nickname' => ['type' => Type::string()], 'barkVolume' => ['type' => Type::int()], 'barks' => ['type' => Type::boolean()], 'doesKnowCommand' => ['type' => Type::boolean(), 'args' => ['dogCommand' => ['type' => $DogCommand]]], 'isHousetrained' => ['type' => Type::boolean(), 'args' => ['atOtherHomes' => ['type' => Type::boolean(), 'defaultValue' => true]]], 'isAtLocation' => ['type' => Type::boolean(), 'args' => ['x' => ['type' => Type::int()], 'y' => ['type' => Type::int()]]]], 'interfaces' => [$Being, $Pet]]);
     $FurColor = new EnumType(['name' => 'FurColor', 'values' => ['BROWN' => ['value' => 0], 'BLACK' => ['value' => 1], 'TAN' => ['value' => 2], 'SPOTTED' => ['value' => 3]]]);
     $Cat = new ObjectType(['name' => 'Cat', 'fields' => ['name' => ['type' => Type::string()], 'nickname' => ['type' => Type::string()], 'meows' => ['type' => Type::boolean()], 'meowVolume' => ['type' => Type::int()], 'furColor' => ['type' => $FurColor]], 'interfaces' => [$Being, $Pet]]);
     $CatOrDog = new UnionType(['name' => 'CatOrDog', 'types' => [$Dog, $Cat], 'resolveType' => function ($value) {
         // not used for validation
         return null;
     }]);
     $Intelligent = new InterfaceType(['name' => 'Intelligent', 'fields' => ['iq' => ['type' => Type::int()]]]);
     $Human = $this->humanType = new ObjectType(['name' => 'Human', 'interfaces' => [$Being, $Intelligent], 'fields' => ['name' => ['args' => ['surname' => ['type' => Type::boolean()]], 'type' => Type::string()], 'pets' => ['type' => Type::listOf($Pet)], 'relatives' => ['type' => function () {
         return Type::listOf($this->humanType);
     }]]]);
     $Alien = new ObjectType(['name' => 'Alien', 'interfaces' => [$Being, $Intelligent], 'fields' => ['iq' => ['type' => Type::int()], 'numEyes' => ['type' => Type::int()]]]);
     $DogOrHuman = new UnionType(['name' => 'DogOrHuman', 'types' => [$Dog, $Human], 'resolveType' => function () {
         // not used for validation
         return null;
     }]);
     $HumanOrAlien = new UnionType(['name' => 'HumanOrAlien', 'types' => [$Human, $Alien], 'resolveType' => function () {
         // not used for validation
         return null;
     }]);
     $ComplexInput = new InputObjectType(['name' => 'ComplexInput', 'fields' => ['requiredField' => ['type' => Type::nonNull(Type::boolean())], 'intField' => ['type' => Type::int()], 'stringField' => ['type' => Type::string()], 'booleanField' => ['type' => Type::boolean()], 'stringListField' => ['type' => Type::listOf(Type::string())]]]);
     $ComplicatedArgs = new ObjectType(['name' => 'ComplicatedArgs', 'fields' => ['intArgField' => ['type' => Type::string(), 'args' => ['intArg' => ['type' => Type::int()]]], 'nonNullIntArgField' => ['type' => Type::string(), 'args' => ['nonNullIntArg' => ['type' => Type::nonNull(Type::int())]]], 'stringArgField' => ['type' => Type::string(), 'args' => ['stringArg' => ['type' => Type::string()]]], 'booleanArgField' => ['type' => Type::string(), 'args' => ['booleanArg' => ['type' => Type::boolean()]]], 'enumArgField' => ['type' => Type::string(), 'args' => ['enumArg' => ['type' => $FurColor]]], 'floatArgField' => ['type' => Type::string(), 'args' => ['floatArg' => ['type' => Type::float()]]], 'idArgField' => ['type' => Type::string(), 'args' => ['idArg' => ['type' => Type::id()]]], 'stringListArgField' => ['type' => Type::string(), 'args' => ['stringListArg' => ['type' => Type::listOf(Type::string())]]], 'complexArgField' => ['type' => Type::string(), 'args' => ['complexArg' => ['type' => $ComplexInput]]], 'multipleReqs' => ['type' => Type::string(), 'args' => ['req1' => ['type' => Type::nonNull(Type::int())], 'req2' => ['type' => Type::nonNull(Type::int())]]], 'multipleOpts' => ['type' => Type::string(), 'args' => ['opt1' => ['type' => Type::int(), 'defaultValue' => 0], 'opt2' => ['type' => Type::int(), 'defaultValue' => 0]]], 'multipleOptAndReq' => ['type' => Type::string(), 'args' => ['req1' => ['type' => Type::nonNull(Type::int())], 'req2' => ['type' => Type::nonNull(Type::int())], 'opt1' => ['type' => Type::int(), 'defaultValue' => 0], 'opt2' => ['type' => Type::int(), 'defaultValue' => 0]]]]]);
     $queryRoot = new ObjectType(['name' => 'QueryRoot', 'fields' => ['human' => ['args' => ['id' => ['type' => Type::id()]], 'type' => $Human], 'alien' => ['type' => $Alien], 'dog' => ['type' => $Dog], 'cat' => ['type' => $Cat], 'pet' => ['type' => $Pet], 'catOrDog' => ['type' => $CatOrDog], 'dogOrHuman' => ['type' => $DogOrHuman], 'humanOrAlien' => ['type' => $HumanOrAlien], 'complicatedArgs' => ['type' => $ComplicatedArgs]]]);
     $defaultSchema = new Schema($queryRoot);
     return $defaultSchema;
 }
コード例 #2
0
 /**
  * @param string $name
  * @return Type
  */
 public function resolveType($name)
 {
     if (preg_match('#^(.+)\\!$#', $name, $regs)) {
         return Type::nonNull($this->resolveType($regs[1]));
     }
     if (preg_match('#^\\[(.+)\\]$#', $name, $regs)) {
         return Type::listOf($this->resolveType($regs[1]));
     }
     switch ($name) {
         case Type::INT:
             return Type::int();
         case Type::STRING:
             return Type::string();
         case Type::BOOLEAN:
             return Type::boolean();
         case Type::FLOAT:
             return Type::float();
         case Type::ID:
             return Type::id();
         default:
             if (!isset($this->types[$name])) {
                 throw new \InvalidArgumentException(sprintf('Type "%s" is not defined', $name));
             }
             return $this->types[$name];
     }
 }
コード例 #3
0
 public function setUp()
 {
     $NamedType = new InterfaceType(['name' => 'Named', 'fields' => ['name' => ['type' => Type::string()]]]);
     $DogType = new ObjectType(['name' => 'Dog', 'interfaces' => [$NamedType], 'fields' => ['name' => ['type' => Type::string()], 'barks' => ['type' => Type::boolean()]], 'isTypeOf' => function ($value) {
         return $value instanceof Dog;
     }]);
     $CatType = new ObjectType(['name' => 'Cat', 'interfaces' => [$NamedType], 'fields' => ['name' => ['type' => Type::string()], 'meows' => ['type' => Type::boolean()]], 'isTypeOf' => function ($value) {
         return $value instanceof Cat;
     }]);
     $PetType = new UnionType(['name' => 'Pet', 'types' => [$DogType, $CatType], 'resolveType' => function ($value) use($DogType, $CatType) {
         if ($value instanceof Dog) {
             return $DogType;
         }
         if ($value instanceof Cat) {
             return $CatType;
         }
     }]);
     $PersonType = new ObjectType(['name' => 'Person', 'interfaces' => [$NamedType], 'fields' => ['name' => ['type' => Type::string()], 'pets' => ['type' => Type::listOf($PetType)], 'friends' => ['type' => Type::listOf($NamedType)]], 'isTypeOf' => function ($value) {
         return $value instanceof Person;
     }]);
     $this->schema = new Schema($PersonType);
     $this->garfield = new Cat('Garfield', false);
     $this->odie = new Dog('Odie', true);
     $this->liz = new Person('Liz');
     $this->john = new Person('John', [$this->garfield, $this->odie], [$this->liz, $this->odie]);
 }
コード例 #4
0
    public function testFieldSelection()
    {
        $image = new ObjectType(['name' => 'Image', 'fields' => ['url' => ['type' => Type::string()], 'width' => ['type' => Type::int()], 'height' => ['type' => Type::int()]]]);
        $article = null;
        $author = new ObjectType(['name' => 'Author', 'fields' => function () use($image, &$article) {
            return ['id' => ['type' => Type::string()], 'name' => ['type' => Type::string()], 'pic' => ['type' => $image, 'args' => ['width' => ['type' => Type::int()], 'height' => ['type' => Type::int()]]], 'recentArticle' => ['type' => $article]];
        }]);
        $reply = new ObjectType(['name' => 'Reply', 'fields' => ['author' => ['type' => $author], 'body' => ['type' => Type::string()]]]);
        $article = new ObjectType(['name' => 'Article', 'fields' => ['id' => ['type' => Type::string()], 'isPublished' => ['type' => Type::boolean()], 'author' => ['type' => $author], 'title' => ['type' => Type::string()], 'body' => ['type' => Type::string()], 'image' => ['type' => $image], 'replies' => ['type' => Type::listOf($reply)]]]);
        $doc = '
      query Test {
        article {
            author {
                name
                pic {
                    url
                    width
                }
            }
            image {
                width
                height
            }
            replies {
                body
                author {
                    id
                    name
                    pic {
                        url
                        width
                    }
                    recentArticle {
                        id
                        title
                        body
                    }
                }
            }
        }
      }
';
        $expectedDefaultSelection = ['author' => true, 'image' => true, 'replies' => true];
        $expectedDeepSelection = ['author' => ['name' => true, 'pic' => ['url' => true, 'width' => true]], 'image' => ['width' => true, 'height' => true], 'replies' => ['body' => true, 'author' => ['id' => true, 'name' => true, 'pic' => ['url' => true, 'width' => true], 'recentArticle' => ['id' => true, 'title' => true, 'body' => true]]]];
        $hasCalled = false;
        $actualDefaultSelection = null;
        $actualDeepSelection = null;
        $blogQuery = new ObjectType(['name' => 'Query', 'fields' => ['article' => ['type' => $article, 'resolve' => function ($value, $args, $context, ResolveInfo $info) use(&$hasCalled, &$actualDefaultSelection, &$actualDeepSelection) {
            $hasCalled = true;
            $actualDefaultSelection = $info->getFieldSelection();
            $actualDeepSelection = $info->getFieldSelection(5);
            return null;
        }]]]);
        $schema = new Schema(['query' => $blogQuery]);
        $result = GraphQL::execute($schema, $doc);
        $this->assertTrue($hasCalled);
        $this->assertEquals(['data' => ['article' => null]], $result);
        $this->assertEquals($expectedDefaultSelection, $actualDefaultSelection);
        $this->assertEquals($expectedDeepSelection, $actualDeepSelection);
    }
コード例 #5
0
 public function getType()
 {
     if (null === $this->resolvedType) {
         $this->resolvedType = Type::resolve($this->type);
     }
     return $this->resolvedType;
 }
コード例 #6
0
 public function setup()
 {
     $this->allUsers = [['name' => 'Dan', 'friends' => [1, 2, 3, 4]], ['name' => 'Nick', 'friends' => [0, 2, 3, 4]], ['name' => 'Lee', 'friends' => [0, 1, 3, 4]], ['name' => 'Joe', 'friends' => [0, 1, 2, 4]], ['name' => 'Tim', 'friends' => [0, 1, 2, 3]]];
     $this->userType = new ObjectType(['name' => 'User', 'fields' => function () {
         return ['name' => ['type' => Type::string()], 'friends' => ['type' => $this->friendConnection, 'args' => Connection::connectionArgs(), 'resolve' => function ($user, $args) {
             return ArrayConnection::connectionFromArray($user['friends'], $args);
         }], 'friendsForward' => ['type' => $this->userConnection, 'args' => Connection::forwardConnectionArgs(), 'resolve' => function ($user, $args) {
             return ArrayConnection::connectionFromArray($user['friends'], $args);
         }], 'friendsBackward' => ['type' => $this->userConnection, 'args' => Connection::backwardConnectionArgs(), 'resolve' => function ($user, $args) {
             return ArrayConnection::connectionFromArray($user['friends'], $args);
         }]];
     }]);
     $this->friendEdge = Connection::createEdgeType(['name' => 'Friend', 'nodeType' => $this->userType, 'resolveNode' => function ($edge) {
         return $this->allUsers[$edge['node']];
     }, 'edgeFields' => function () {
         return ['friendshipTime' => ['type' => Type::string(), 'resolve' => function () {
             return 'Yesterday';
         }]];
     }]);
     $this->friendConnection = Connection::createConnectionType(['name' => 'Friend', 'nodeType' => $this->userType, 'edgeType' => $this->friendEdge, 'connectionFields' => function () {
         return ['totalCount' => ['type' => Type::int(), 'resolve' => function () {
             return count($this->allUsers) - 1;
         }]];
     }]);
     $this->userEdge = Connection::createEdgeType(['nodeType' => $this->userType, 'resolveNode' => function ($edge) {
         return $this->allUsers[$edge['node']];
     }]);
     $this->userConnection = Connection::createConnectionType(['nodeType' => $this->userType, 'edgeType' => $this->userEdge]);
     $this->queryType = new ObjectType(['name' => 'Query', 'fields' => function () {
         return ['user' => ['type' => $this->userType, 'resolve' => function () {
             return $this->allUsers[0];
         }]];
     }]);
     $this->schema = new Schema(['query' => $this->queryType]);
 }
コード例 #7
0
 public function setUp()
 {
     $this->syncError = new Error('sync');
     $this->nonNullSyncError = new Error('nonNullSync');
     $this->throwingData = ['sync' => function () {
         throw $this->syncError;
     }, 'nonNullSync' => function () {
         throw $this->nonNullSyncError;
     }, 'nest' => function () {
         return $this->throwingData;
     }, 'nonNullNest' => function () {
         return $this->throwingData;
     }];
     $this->nullingData = ['sync' => function () {
         return null;
     }, 'nonNullSync' => function () {
         return null;
     }, 'nest' => function () {
         return $this->nullingData;
     }, 'nonNullNest' => function () {
         return $this->nullingData;
     }];
     $dataType = new ObjectType(['name' => 'DataType', 'fields' => ['sync' => ['type' => Type::string()], 'nonNullSync' => ['type' => Type::nonNull(Type::string())], 'nest' => ['type' => function () use(&$dataType) {
         return $dataType;
     }], 'nonNullNest' => ['type' => function () use(&$dataType) {
         return Type::nonNull($dataType);
     }]]]);
     $this->schema = new Schema($dataType);
 }
コード例 #8
0
ファイル: UserType.php プロジェクト: nuwave/lighthouse
 /**
  * Type fields.
  *
  * @return array
  */
 public function fields()
 {
     return ['name' => ['type' => Type::string(), 'description' => 'Name of the user.'], 'email' => ['type' => Type::string(), 'description' => 'Email of the user.'], 'tasks' => GraphQL::connection('task')->args(['order' => ['type' => Type::string(), 'description' => 'Sort order of tasks.']])->resolve(function ($parent, array $args) {
         return $parent->tasks->transform(function ($task) {
             return array_merge($task->toArray(), ['title' => 'foo']);
         });
     })->field()];
 }
コード例 #9
0
 public static function buildDogType()
 {
     if (null !== self::$dogType) {
         return self::$dogType;
     }
     self::$dogType = new ObjectType(['name' => 'Dog', 'fields' => ['name' => ['type' => Type::nonNull(Type::string())], 'master' => ['type' => self::buildHumanType()]]]);
     return self::$dogType;
 }
コード例 #10
0
ファイル: QueryType.php プロジェクト: webonyx/graphql-php
 public function __construct()
 {
     $config = ['name' => 'Query', 'fields' => ['user' => ['type' => Types::user(), 'description' => 'Returns user by id (in range of 1-5)', 'args' => ['id' => Types::nonNull(Types::id())]], 'viewer' => ['type' => Types::user(), 'description' => 'Represents currently logged-in user (for the sake of example - simply returns user with id == 1)'], 'stories' => ['type' => Types::listOf(Types::story()), 'description' => 'Returns subset of stories posted for this blog', 'args' => ['after' => ['type' => Types::id(), 'description' => 'Fetch stories listed after the story with this ID'], 'limit' => ['type' => Types::int(), 'description' => 'Number of stories to be returned', 'defaultValue' => 10]]], 'lastStoryPosted' => ['type' => Types::story(), 'description' => 'Returns last story posted for this blog'], 'deprecatedField' => ['type' => Types::string(), 'deprecationReason' => 'This field is deprecated!'], 'fieldWithException' => ['type' => Types::string(), 'resolve' => function () {
         throw new \Exception("Exception message thrown in field resolver");
     }], 'hello' => Type::string()], 'resolveField' => function ($val, $args, $context, ResolveInfo $info) {
         return $this->{$info->fieldName}($val, $args, $context, $info);
     }];
     parent::__construct($config);
 }
コード例 #11
0
 /**
  * Returns the test ObjectType
  * @return ObjectType
  */
 protected function getTestObjectType()
 {
     if (!$this->testObject) {
         $this->testObject = new ObjectType(['name' => 'TestObject', 'fields' => ['name' => ['type' => Type::string(), 'resolve' => function () {
             return 'testname';
         }]], 'interfaces' => [$this->getLazyInterfaceType()]]);
     }
     return $this->testObject;
 }
コード例 #12
0
ファイル: EnumTypeTest.php プロジェクト: webonyx/graphql-php
 public function setUp()
 {
     $ColorType = new EnumType(['name' => 'Color', 'values' => ['RED' => ['value' => 0], 'GREEN' => ['value' => 1], 'BLUE' => ['value' => 2]]]);
     $simpleEnum = new EnumType(['name' => 'SimpleEnum', 'values' => ['ONE', 'TWO', 'THREE']]);
     $Complex1 = ['someRandomFunction' => function () {
     }];
     $Complex2 = new \ArrayObject(['someRandomValue' => 123]);
     $ComplexEnum = new EnumType(['name' => 'Complex', 'values' => ['ONE' => ['value' => $Complex1], 'TWO' => ['value' => $Complex2]]]);
     $QueryType = new ObjectType(['name' => 'Query', 'fields' => ['colorEnum' => ['type' => $ColorType, 'args' => ['fromEnum' => ['type' => $ColorType], 'fromInt' => ['type' => Type::int()], 'fromString' => ['type' => Type::string()]], 'resolve' => function ($value, $args) {
         if (isset($args['fromInt'])) {
             return $args['fromInt'];
         }
         if (isset($args['fromString'])) {
             return $args['fromString'];
         }
         if (isset($args['fromEnum'])) {
             return $args['fromEnum'];
         }
     }], 'simpleEnum' => ['type' => $simpleEnum, 'args' => ['fromName' => ['type' => Type::string()], 'fromValue' => ['type' => Type::string()]], 'resolve' => function ($value, $args) {
         if (isset($args['fromName'])) {
             return $args['fromName'];
         }
         if (isset($args['fromValue'])) {
             return $args['fromValue'];
         }
     }], 'colorInt' => ['type' => Type::int(), 'args' => ['fromEnum' => ['type' => $ColorType], 'fromInt' => ['type' => Type::int()]], 'resolve' => function ($value, $args) {
         if (isset($args['fromInt'])) {
             return $args['fromInt'];
         }
         if (isset($args['fromEnum'])) {
             return $args['fromEnum'];
         }
     }], 'complexEnum' => ['type' => $ComplexEnum, 'args' => ['fromEnum' => ['type' => $ComplexEnum, 'defaultValue' => $Complex1], 'provideGoodValue' => ['type' => Type::boolean()], 'provideBadValue' => ['type' => Type::boolean()]], 'resolve' => function ($value, $args) use($Complex1, $Complex2) {
         if (!empty($args['provideGoodValue'])) {
             // Note: this is one of the references of the internal values which
             // ComplexEnum allows.
             return $Complex2;
         }
         if (!empty($args['provideBadValue'])) {
             // Note: similar shape, but not the same *reference*
             // as Complex2 above. Enum internal values require === equality.
             return new \ArrayObject(['someRandomValue' => 123]);
         }
         return $args['fromEnum'];
     }]]]);
     $MutationType = new ObjectType(['name' => 'Mutation', 'fields' => ['favoriteEnum' => ['type' => $ColorType, 'args' => ['color' => ['type' => $ColorType]], 'resolve' => function ($value, $args) {
         return isset($args['color']) ? $args['color'] : null;
     }]]]);
     $SubscriptionType = new ObjectType(['name' => 'Subscription', 'fields' => ['subscribeToEnum' => ['type' => $ColorType, 'args' => ['color' => ['type' => $ColorType]], 'resolve' => function ($value, $args) {
         return isset($args['color']) ? $args['color'] : null;
     }]]]);
     $this->Complex1 = $Complex1;
     $this->Complex2 = $Complex2;
     $this->ComplexEnum = $ComplexEnum;
     $this->schema = new Schema(['query' => $QueryType, 'mutation' => $MutationType, 'subscription' => $SubscriptionType]);
 }
コード例 #13
0
ファイル: ListsTest.php プロジェクト: aeshion/ZeroPHP
 /**
  * @describe [T!]!
  */
 public function testHandlesNonNullListOfNonNulls()
 {
     $type = Type::nonNull(Type::listOf(Type::nonNull(Type::int())));
     // Contains values
     $this->check($type, [1, 2], ['data' => ['nest' => ['test' => [1, 2]]]]);
     // Contains null
     $this->check($type, [1, null, 2], ['data' => ['nest' => null], 'errors' => [FormattedError::create('Cannot return null for non-nullable field DataType.test.', [new SourceLocation(1, 10)])]]);
     // Returns null
     $this->check($type, null, ['data' => ['nest' => null], 'errors' => [FormattedError::create('Cannot return null for non-nullable field DataType.test.', [new SourceLocation(1, 10)])]]);
 }
コード例 #14
0
ファイル: ResolveTest.php プロジェクト: webonyx/graphql-php
 /**
  * @it uses provided resolve function
  */
 public function testUsesProvidedResolveFunction()
 {
     $schema = $this->buildSchema(['type' => Type::string(), 'args' => ['aStr' => ['type' => Type::string()], 'aInt' => ['type' => Type::int()]], 'resolve' => function ($source, $args) {
         return json_encode([$source, $args]);
     }]);
     $this->assertEquals(['data' => ['test' => '[null,[]]']], GraphQL::execute($schema, '{ test }'));
     $this->assertEquals(['data' => ['test' => '["Source!",[]]']], GraphQL::execute($schema, '{ test }', 'Source!'));
     $this->assertEquals(['data' => ['test' => '["Source!",{"aStr":"String!"}]']], GraphQL::execute($schema, '{ test(aStr: "String!") }', 'Source!'));
     $this->assertEquals(['data' => ['test' => '["Source!",{"aStr":"String!","aInt":-123}]']], GraphQL::execute($schema, '{ test(aInt: -123, aStr: "String!") }', 'Source!'));
 }
コード例 #15
0
ファイル: Schema.php プロジェクト: rtuin/graphql-php
 public function getTypeMap()
 {
     if (null === $this->_typeMap) {
         $map = [];
         foreach ([$this->getQueryType(), $this->getMutationType(), Introspection::_schema()] as $type) {
             $this->_extractTypes($type, $map);
         }
         $this->_typeMap = $map + Type::getInternalTypes();
     }
     return $this->_typeMap;
 }
コード例 #16
0
 public function testCoercesOutputBoolean()
 {
     $boolType = Type::boolean();
     $this->assertSame(true, $boolType->coerce('string'));
     $this->assertSame(false, $boolType->coerce(''));
     $this->assertSame(true, $boolType->coerce(1));
     $this->assertSame(false, $boolType->coerce(0));
     $this->assertSame(true, $boolType->coerce(true));
     $this->assertSame(false, $boolType->coerce(false));
     // TODO: how should it behaive on '0'?
 }
コード例 #17
0
 public function __invoke(ValidationContext $context)
 {
     return [NodeKind::VARIABLE_DEFINITION => function (VariableDefinitionNode $node) use($context) {
         $type = Utils\TypeInfo::typeFromAST($context->getSchema(), $node->type);
         // If the variable type is not an input type, return an error.
         if ($type && !Type::isInputType($type)) {
             $variableName = $node->variable->name->value;
             $context->reportError(new Error(self::nonInputTypeOnVarMessage($variableName, Printer::doPrint($node->type)), [$node->type]));
         }
     }];
 }
コード例 #18
0
 protected static function getSchema()
 {
     $userType = new ObjectType(['name' => 'User', 'fields' => function () {
         return ['username' => ['type' => Type::string()], 'url' => ['type' => Type::string()]];
     }]);
     $queryType = new ObjectType(['name' => 'Query', 'fields' => function () use($userType) {
         return ['usernames' => Plural::pluralIdentifyingRootField(['argName' => 'usernames', 'description' => 'Map from a username to the user', 'inputType' => Type::string(), 'outputType' => $userType, 'resolveSingleInput' => function ($userName, $context, $info) {
             return ['username' => $userName, 'url' => 'www.facebook.com/' . $userName . '?lang=' . $info->rootValue['lang']];
         }])];
     }]);
     return new Schema(['query' => $queryType]);
 }
コード例 #19
0
ファイル: Plural.php プロジェクト: ivome/graphql-relay-php
 /**
  * Returns configuration for Plural identifying root field
  *
  * type PluralIdentifyingRootFieldConfig = {
  *       argName: string,
  *       inputType: GraphQLInputType,
  *       outputType: GraphQLOutputType,
  *       resolveSingleInput: (input: any, info: GraphQLResolveInfo) => ?any,
  *       description?: ?string,
  * };
  *
  * @param array $config
  * @return array
  */
 public static function pluralIdentifyingRootField(array $config)
 {
     $inputArgs = [];
     $argName = self::getArrayValue($config, 'argName');
     $inputArgs[$argName] = ['type' => Type::nonNull(Type::listOf(Type::nonNull(self::getArrayValue($config, 'inputType'))))];
     return ['description' => isset($config['description']) ? $config['description'] : null, 'type' => Type::listOf(self::getArrayValue($config, 'outputType')), 'args' => $inputArgs, 'resolve' => function ($obj, $args, $context, ResolveInfo $info) use($argName, $config) {
         $inputs = $args[$argName];
         return array_map(function ($input) use($config, $context, $info) {
             return call_user_func(self::getArrayValue($config, 'resolveSingleInput'), $input, $context, $info);
         }, $inputs);
     }];
 }
コード例 #20
0
    public function testExecutesUsingASchema()
    {
        $BlogArticle = null;
        $BlogImage = new ObjectType(['name' => 'Image', 'fields' => ['url' => ['type' => Type::string()], 'width' => ['type' => Type::int()], 'height' => ['type' => Type::int()]]]);
        $BlogAuthor = new ObjectType(['name' => 'Author', 'fields' => ['id' => ['type' => Type::string()], 'name' => ['type' => Type::string()], 'pic' => ['args' => ['width' => ['type' => Type::int()], 'height' => ['type' => Type::int()]], 'type' => $BlogImage, 'resolve' => function ($obj, $args) {
            return $obj['pic']($args['width'], $args['height']);
        }], 'recentArticle' => ['type' => function () use(&$BlogArticle) {
            return $BlogArticle;
        }]]]);
        $BlogArticle = new ObjectType(['name' => 'Article', 'fields' => ['id' => ['type' => Type::nonNull(Type::string())], 'isPublished' => ['type' => Type::boolean()], 'author' => ['type' => $BlogAuthor], 'title' => ['type' => Type::string()], 'body' => ['type' => Type::string()], 'keywords' => ['type' => Type::listOf(Type::string())]]]);
        $BlogQuery = new ObjectType(['name' => 'Query', 'fields' => ['article' => ['type' => $BlogArticle, 'args' => ['id' => ['type' => Type::id()]], 'resolve' => function ($_, $args) {
            return $this->article($args['id']);
        }], 'feed' => ['type' => Type::listOf($BlogArticle), 'resolve' => function () {
            return [$this->article(1), $this->article(2), $this->article(3), $this->article(4), $this->article(5), $this->article(6), $this->article(7), $this->article(8), $this->article(9), $this->article(10)];
        }]]]);
        $BlogSchema = new Schema($BlogQuery);
        $request = '
      {
        feed {
          id,
          title
        },
        article(id: "1") {
          ...articleFields,
          author {
            id,
            name,
            pic(width: 640, height: 480) {
              url,
              width,
              height
            },
            recentArticle {
              ...articleFields,
              keywords
            }
          }
        }
      }

      fragment articleFields on Article {
        id,
        isPublished,
        title,
        body,
        hidden,
        notdefined
      }
    ';
        $expected = ['data' => ['feed' => [['id' => '1', 'title' => 'My Article 1'], ['id' => '2', 'title' => 'My Article 2'], ['id' => '3', 'title' => 'My Article 3'], ['id' => '4', 'title' => 'My Article 4'], ['id' => '5', 'title' => 'My Article 5'], ['id' => '6', 'title' => 'My Article 6'], ['id' => '7', 'title' => 'My Article 7'], ['id' => '8', 'title' => 'My Article 8'], ['id' => '9', 'title' => 'My Article 9'], ['id' => '10', 'title' => 'My Article 10']], 'article' => ['id' => '1', 'isPublished' => true, 'title' => 'My Article 1', 'body' => 'This is a post', 'author' => ['id' => '123', 'name' => 'John Smith', 'pic' => ['url' => 'cdn://123', 'width' => 640, 'height' => 480], 'recentArticle' => ['id' => '1', 'isPublished' => true, 'title' => 'My Article 1', 'body' => 'This is a post', 'keywords' => ['foo', 'bar', '1', 'true', null]]]]]];
        $this->assertEquals($expected, Executor::execute($BlogSchema, Parser::parse($request))->toArray());
    }
コード例 #21
0
ファイル: EdgeType.php プロジェクト: nuwave/lighthouse
 /**
  * Fields that exist on every connection.
  *
  * @return array
  */
 public function fields()
 {
     return ['node' => ['type' => $this->type, 'description' => 'The item at the end of the edge.', 'resolve' => function ($edge) {
         return $edge;
     }], 'cursor' => ['type' => Type::nonNull(Type::string()), 'description' => 'A cursor for use in pagination.', 'resolve' => function ($edge) {
         if (is_array($edge) && isset($edge['relayCursor'])) {
             return $edge['relayCursor'];
         } elseif (is_array($edge->attributes)) {
             return $edge->attributes['relayCursor'];
         }
         return $edge->relayCursor;
     }]];
 }
コード例 #22
0
 /**
  * Fields available on PageInfo.
  *
  * @return array
  */
 public function fields()
 {
     return ['hasNextPage' => ['type' => Type::nonNull(Type::boolean()), 'description' => 'When paginating forwards, are there more items?', 'resolve' => function ($collection, $test) {
         if ($collection['total'] - $collection['first'] * $collection['currentPage'] > 0) {
             return true;
         }
         return false;
     }], 'hasPreviousPage' => ['type' => Type::nonNull(Type::boolean()), 'description' => 'When paginating backwards, are there more items?', 'resolve' => function ($collection) {
         if ($collection['currentPage'] > 1) {
             return true;
         }
         return false;
     }]];
 }
コード例 #23
0
ファイル: MutationsTest.php プロジェクト: aeshion/ZeroPHP
 private function schema()
 {
     $numberHolderType = new ObjectType(['fields' => ['theNumber' => ['type' => Type::int()]], 'name' => 'NumberHolder']);
     $schema = new Schema(['query' => new ObjectType(['fields' => ['numberHolder' => ['type' => $numberHolderType]], 'name' => 'Query']), 'mutation' => new ObjectType(['fields' => ['immediatelyChangeTheNumber' => ['type' => $numberHolderType, 'args' => ['newNumber' => ['type' => Type::int()]], 'resolve' => function (Root $obj, $args) {
         return $obj->immediatelyChangeTheNumber($args['newNumber']);
     }], 'promiseToChangeTheNumber' => ['type' => $numberHolderType, 'args' => ['newNumber' => ['type' => Type::int()]], 'resolve' => function (Root $obj, $args) {
         return $obj->promiseToChangeTheNumber($args['newNumber']);
     }], 'failToChangeTheNumber' => ['type' => $numberHolderType, 'args' => ['newNumber' => ['type' => Type::int()]], 'resolve' => function (Root $obj, $args) {
         return $obj->failToChangeTheNumber($args['newNumber']);
     }], 'promiseAndFailToChangeTheNumber' => ['type' => $numberHolderType, 'args' => ['newNumber' => ['type' => Type::int()]], 'resolve' => function (Root $obj, $args) {
         return $obj->promiseAndFailToChangeTheNumber($args['newNumber']);
     }]], 'name' => 'Mutation'])]);
     return $schema;
 }
コード例 #24
0
 public function __invoke(ValidationContext $context)
 {
     return [Node::INLINE_FRAGMENT => function (InlineFragment $node) use($context) {
         $type = $context->getType();
         if ($node->typeCondition && $type && !Type::isCompositeType($type)) {
             $context->reportError(new Error(static::inlineFragmentOnNonCompositeErrorMessage($type), [$node->typeCondition]));
         }
     }, Node::FRAGMENT_DEFINITION => function (FragmentDefinition $node) use($context) {
         $type = $context->getType();
         if ($type && !Type::isCompositeType($type)) {
             $context->reportError(new Error(static::fragmentOnNonCompositeErrorMessage($node->name->value, Printer::doPrint($node->typeCondition)), [$node->typeCondition]));
         }
     }];
 }
コード例 #25
0
ファイル: UnionType.php プロジェクト: webonyx/graphql-php
 /**
  * @return ObjectType[]
  */
 public function getTypes()
 {
     if (null === $this->types) {
         if ($this->config['types'] instanceof \Closure) {
             $types = call_user_func($this->config['types']);
         } else {
             $types = $this->config['types'];
         }
         Utils::invariant(is_array($types), 'Option "types" of union "%s" is expected to return array of types (or closure returning array of types)', $this->name);
         $this->types = [];
         foreach ($types as $type) {
             $this->types[] = Type::resolve($type);
         }
     }
     return $this->types;
 }
コード例 #26
0
ファイル: ScalarLeafs.php プロジェクト: rtuin/graphql-php
 public function __invoke(ValidationContext $context)
 {
     return [Node::FIELD => function (Field $node) use($context) {
         $type = $context->getType();
         if ($type) {
             if (Type::isLeafType($type)) {
                 if ($node->selectionSet) {
                     return new Error(Messages::noSubselectionAllowedMessage($node->name->value, $type), [$node->selectionSet]);
                 }
             } else {
                 if (!$node->selectionSet) {
                     return new Error(Messages::requiredSubselectionMessage($node->name->value, $type), [$node]);
                 }
             }
         }
     }];
 }
コード例 #27
0
 public function __invoke(ValidationContext $context)
 {
     return [Node::INLINE_FRAGMENT => function (InlineFragment $node) use($context) {
         $fragType = Type::getUnmodifiedType($context->getType());
         $parentType = $context->getParentType();
         if ($fragType && $parentType && !$this->doTypesOverlap($fragType, $parentType)) {
             return new Error(Messages::typeIncompatibleAnonSpreadMessage($parentType, $fragType), [$node]);
         }
     }, Node::FRAGMENT_SPREAD => function (FragmentSpread $node) use($context) {
         $fragName = $node->name->value;
         $fragType = Type::getUnmodifiedType($this->getFragmentType($context, $fragName));
         $parentType = $context->getParentType();
         if ($fragType && $parentType && !$this->doTypesOverlap($fragType, $parentType)) {
             return new Error(Messages::typeIncompatibleSpreadMessage($fragName, $parentType, $fragType), [$node]);
         }
     }];
 }
コード例 #28
0
ファイル: MenuItem.php プロジェクト: dobbit/graphql-wp
 function getConfig($config)
 {
     return array_replace_recursive(['description' => 'Items in a navigation menu', 'fields' => ['id' => ['type' => Type::string(), 'description' => 'Unique id for menu item', 'resolve' => function ($item) {
         return $item->object_id;
     }], 'caption' => ['type' => Type::string(), 'description' => 'File caption', 'resolve' => function ($item) {
         return $item->caption;
     }], 'title' => ['type' => Type::string(), 'description' => 'File title', 'resolve' => function ($item) {
         return $item->title;
     }], 'target' => ['type' => Type::string(), 'description' => 'Link target', 'resolve' => function ($item) {
         return $item->target;
     }], 'url' => ['type' => Type::string(), 'description' => 'Menu url', 'resolve' => function ($item) {
         return $item->url;
     }], 'description' => ['type' => Type::string(), 'description' => 'Link description', 'resolve' => function ($item) {
         return $item->description;
     }], 'classes' => ['type' => new ListOfType(Type::string()), 'description' => 'CSS class names for this item', 'resolve' => function ($item) {
         return $item->classes;
     }]]], $config);
 }
コード例 #29
0
ファイル: PageInfoType.php プロジェクト: nuwave/lighthouse
 /**
  * Fields available on PageInfo.
  *
  * @return array
  */
 public function fields()
 {
     return ['hasNextPage' => ['type' => Type::nonNull(Type::boolean()), 'description' => 'When paginating forwards, are there more items?', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->hasMorePages();
         }
         return false;
     }], 'hasPreviousPage' => ['type' => Type::nonNull(Type::boolean()), 'description' => 'When paginating backwards, are there more items?', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->currentPage() > 1;
         }
         return false;
     }], 'startCursor' => ['type' => Type::string(), 'description' => 'When paginating backwards, the cursor to continue.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $this->encodeGlobalId('arrayconnection', $collection->firstItem() * $collection->currentPage());
         }
         return null;
     }], 'endCursor' => ['type' => Type::string(), 'description' => 'When paginating forwards, the cursor to continue.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $this->encodeGlobalId('arrayconnection', $collection->lastItem() * $collection->currentPage());
         }
         return null;
     }], 'total' => ['type' => Type::int(), 'description' => 'Total number of node in connection.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->total();
         }
         return null;
     }], 'count' => ['type' => Type::int(), 'description' => 'Count of nodes in current request.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->count();
         }
         return null;
     }], 'currentPage' => ['type' => Type::int(), 'description' => 'Current page of request.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->currentPage();
         }
         return null;
     }], 'lastPage' => ['type' => Type::int(), 'description' => 'Last page in connection.', 'resolve' => function ($collection) {
         if ($collection instanceof LengthAwarePaginator) {
             return $collection->lastPage();
         }
         return null;
     }]];
 }
コード例 #30
0
ファイル: ACFImage.php プロジェクト: dobbit/graphql-wp
 function getConfig($config)
 {
     return array_replace_recursive(['description' => 'An image from the ACF plugin', 'fields' => ['caption' => ['description' => 'Image caption'], 'title' => ['description' => 'Image title'], 'url' => ['description' => 'Image path', 'args' => ['size' => ['description' => 'size of the image', 'type' => Type::string()]], 'resolve' => function ($field, $args) {
         $args += ['size' => 'medium'];
         $size = $args['size'];
         if ($size == 'full') {
             return $field['url'];
         }
         return $field['sizes'][$size];
     }], 'width' => ['type' => Type::int(), 'description' => 'Image width', 'args' => ['size' => ['description' => 'size of the image', 'type' => Type::string()]], 'resolve' => function ($field) {
         $args += ['size' => 'medium'];
         $size = $args['size'];
         return $field['sizes'][$size . '-width'];
     }], 'height' => ['type' => Type::int(), 'description' => 'Image width', 'args' => ['size' => ['description' => 'size of the image', 'type' => Type::string()]], 'resolve' => function ($post) {
         $args += ['size' => 'medium'];
         $size = $args['size'];
         return $field['sizes'][$size . '-height'];
     }]]], parent::getConfig($config));
 }