Acts as a registry and factory for your types. As simplistic as possible for the sake of clarity of this example. Your own may be more dynamic (or even code-generated).
Exemple #1
0
 public static function build($name, $objectKey = null)
 {
     $objectKey = $objectKey ?: $name;
     // Demonstrates how to organize re-usable fields
     // Usual example: when the same field with same args shows up in different types
     // (for example when it is a part of some interface)
     return ['name' => $name, 'type' => Types::string(), 'args' => ['format' => ['type' => Types::contentFormatEnum(), 'defaultValue' => ContentFormatEnum::FORMAT_HTML], 'maxLength' => Types::int()], 'resolve' => function ($object, $args) use($objectKey) {
         $html = $object->{$objectKey};
         $text = strip_tags($html);
         if (!empty($args['maxLength'])) {
             $safeText = mb_substr($text, 0, $args['maxLength']);
         } else {
             $safeText = $text;
         }
         switch ($args['format']) {
             case ContentFormatEnum::FORMAT_HTML:
                 if ($safeText !== $text) {
                     // Text was truncated, so just show what's safe:
                     return nl2br($safeText);
                 } else {
                     return $html;
                 }
             case ContentFormatEnum::FORMAT_TEXT:
             default:
                 return $safeText;
         }
     }];
 }
Exemple #2
0
 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);
 }
Exemple #3
0
 public function __construct()
 {
     $config = ['name' => 'ImageType', 'fields' => ['id' => Types::id(), 'type' => new EnumType(['name' => 'ImageTypeEnum', 'values' => ['USERPIC' => Image::TYPE_USERPIC]]), 'size' => Types::imageSizeEnum(), 'width' => Types::int(), 'height' => Types::int(), 'url' => ['type' => Types::url(), 'resolve' => [$this, 'resolveUrl']], 'fieldWithError' => ['type' => Types::string(), 'resolve' => function () {
         throw new \Exception("Field with exception");
     }], 'nonNullFieldWithError' => ['type' => Types::nonNull(Types::string()), 'resolve' => function () {
         throw new \Exception("Non-null field with exception");
     }]]];
     parent::__construct($config);
 }
Exemple #4
0
 public function __construct()
 {
     // Option #2: define type using inheritance, see any other object type for compositional example
     $config = ['name' => 'ImageType', 'fields' => ['id' => Types::id(), 'type' => new EnumType(['name' => 'ImageTypeEnum', 'values' => ['USERPIC' => Image::TYPE_USERPIC]]), 'size' => Types::imageSizeEnum(), 'width' => Types::int(), 'height' => Types::int(), 'url' => ['type' => Types::url(), 'resolve' => [$this, 'resolveUrl']], 'fieldWithError' => ['type' => Types::string(), 'resolve' => function () {
         throw new \Exception("Field with exception");
     }], 'nonNullFieldWithError' => ['type' => Types::nonNull(Types::string()), 'resolve' => function () {
         throw new \Exception("Non-null field with exception");
     }]]];
     parent::__construct($config);
 }
Exemple #5
0
 public function __construct()
 {
     // Option #1: using composition over inheritance to define type, see ImageType for inheritance example
     $this->definition = new ObjectType(['name' => 'Story', 'fields' => function () {
         return ['id' => Types::id(), 'author' => Types::user(), 'mentions' => Types::listOf(Types::mention()), 'totalCommentCount' => Types::int(), 'comments' => ['type' => Types::listOf(Types::comment()), 'args' => ['after' => ['type' => Types::id(), 'description' => 'Load all comments listed after given comment ID'], 'limit' => ['type' => Types::int(), 'defaultValue' => 5]]], 'likes' => ['type' => Types::listOf(Types::user()), 'args' => ['limit' => ['type' => Types::int(), 'description' => 'Limit the number of recent likes returned', 'defaultValue' => 5]]], 'likedBy' => ['type' => Types::listOf(Types::user())], 'affordances' => Types::listOf(new EnumType(['name' => 'StoryAffordancesEnum', 'values' => [self::EDIT, self::DELETE, self::LIKE, self::UNLIKE, self::REPLY]])), 'hasViewerLiked' => Types::boolean(), Types::htmlField('body')];
     }, 'interfaces' => [Types::node()], 'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
         if (method_exists($this, $info->fieldName)) {
             return $this->{$info->fieldName}($value, $args, $context, $info);
         } else {
             return $value->{$info->fieldName};
         }
     }]);
 }
Exemple #6
0
 public function __construct()
 {
     // Option #1: using composition over inheritance to define type, see ImageType for inheritance example
     $this->definition = new ObjectType(['name' => 'Comment', 'fields' => function () {
         return ['id' => Types::id(), 'author' => Types::user(), 'parent' => Types::comment(), 'isAnonymous' => Types::boolean(), 'replies' => ['type' => Types::listOf(Types::comment()), 'args' => ['after' => Types::int(), 'limit' => ['type' => Types::int(), 'defaultValue' => 5]]], 'totalReplyCount' => Types::int(), Types::htmlField('body')];
     }, 'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
         if (method_exists($this, $info->fieldName)) {
             return $this->{$info->fieldName}($value, $args, $context, $info);
         } else {
             return $value->{$info->fieldName};
         }
     }]);
 }
Exemple #7
0
 public function __construct()
 {
     $config = ['name' => 'Comment', 'fields' => function () {
         return ['id' => Types::id(), 'author' => Types::user(), 'parent' => Types::comment(), 'isAnonymous' => Types::boolean(), 'replies' => ['type' => Types::listOf(Types::comment()), 'args' => ['after' => Types::int(), 'limit' => ['type' => Types::int(), 'defaultValue' => 5]]], 'totalReplyCount' => Types::int(), Types::htmlField('body')];
     }, 'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
         if (method_exists($this, $info->fieldName)) {
             return $this->{$info->fieldName}($value, $args, $context, $info);
         } else {
             return $value->{$info->fieldName};
         }
     }];
     parent::__construct($config);
 }
Exemple #8
0
 public function resolveType($object, Types $types)
 {
     if ($object instanceof User) {
         return Types::user();
     } else {
         if ($object instanceof Image) {
             return Types::image();
         } else {
             if ($object instanceof Story) {
                 return Types::story();
             }
         }
     }
 }
 public function __construct()
 {
     $config = ['name' => 'SearchResultType', 'types' => function () {
         return [Types::story(), Types::user()];
     }, 'resolveType' => function ($value) {
         if ($value instanceof Story) {
             return Types::story();
         } else {
             if ($value instanceof User) {
                 return Types::user();
             }
         }
     }];
     parent::__construct($config);
 }
Exemple #10
0
 public function __construct()
 {
     // Option #1: using composition over inheritance to define type, see ImageType for inheritance example
     $this->definition = new UnionType(['name' => 'SearchResultType', 'types' => function () {
         return [Types::story(), Types::user()];
     }, 'resolveType' => function ($value) {
         if ($value instanceof Story) {
             return Types::story();
         } else {
             if ($value instanceof User) {
                 return Types::user();
             }
         }
     }]);
 }
Exemple #11
0
 public function __construct()
 {
     $config = ['name' => 'User', 'description' => 'Our blog authors', 'fields' => function () {
         return ['id' => Types::id(), 'email' => Types::email(), 'photo' => ['type' => Types::image(), 'description' => 'User photo URL', 'args' => ['size' => Types::nonNull(Types::imageSizeEnum())]], 'firstName' => ['type' => Types::string()], 'lastName' => ['type' => Types::string()], 'lastStoryPosted' => Types::story(), 'fieldWithError' => ['type' => Types::string(), 'resolve' => function () {
             throw new \Exception("This is error field");
         }]];
     }, 'interfaces' => [Types::node()], 'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
         if (method_exists($this, $info->fieldName)) {
             return $this->{$info->fieldName}($value, $args, $context, $info);
         } else {
             return $value->{$info->fieldName};
         }
     }];
     parent::__construct($config);
 }
Exemple #12
0
 public function __construct()
 {
     // Option #1: using composition over inheritance to define type, see ImageType for inheritance example
     $this->definition = new ObjectType(['name' => 'User', 'description' => 'Our blog authors', 'fields' => function () {
         return ['id' => Types::id(), 'email' => Types::email(), 'photo' => ['type' => Types::image(), 'description' => 'User photo URL', 'args' => ['size' => Types::nonNull(Types::imageSizeEnum())]], 'firstName' => ['type' => Types::string()], 'lastName' => ['type' => Types::string()], 'lastStoryPosted' => Types::story(), 'fieldWithError' => ['type' => Types::string(), 'resolve' => function () {
             throw new \Exception("This is error field");
         }]];
     }, 'interfaces' => [Types::node()], 'resolveField' => function ($value, $args, $context, ResolveInfo $info) {
         if (method_exists($this, $info->fieldName)) {
             return $this->{$info->fieldName}($value, $args, $context, $info);
         } else {
             return $value->{$info->fieldName};
         }
     }]);
 }
Exemple #13
0
    // simulated "currently logged-in user"
    $appContext->rootUrl = 'http://localhost:8080';
    $appContext->request = $_REQUEST;
    // Parse incoming query and variables
    if (isset($_SERVER['CONTENT_TYPE']) && strpos($_SERVER['CONTENT_TYPE'], 'application/json') !== false) {
        $raw = file_get_contents('php://input') ?: '';
        $data = json_decode($raw, true);
    } else {
        $data = $_REQUEST;
    }
    $data += ['query' => null, 'variables' => null];
    if (null === $data['query']) {
        $data['query'] = '{hello}';
    }
    // GraphQL schema to be passed to query executor:
    $schema = new Schema(['query' => Types::query()]);
    $result = GraphQL::execute($schema, $data['query'], null, $appContext, (array) $data['variables']);
    // Add reported PHP errors to result (if any)
    if (!empty($_GET['debug']) && !empty($phpErrors)) {
        $result['extensions']['phpErrors'] = array_map(['GraphQL\\Error\\FormattedError', 'createFromPHPError'], $phpErrors);
    }
    $httpStatus = 200;
} catch (\Exception $error) {
    $httpStatus = 500;
    if (!empty($_GET['debug'])) {
        $result['extensions']['exception'] = FormattedError::createFromException($error);
    } else {
        $result['errors'] = [FormattedError::create('Unexpected Error')];
    }
}
header('Content-Type: application/json', true, $httpStatus);