public function __construct($config) { if (!isset($config['name'])) { $config['name'] = $this->tryInferName(); } Config::validate($config, ['name' => Config::NAME | Config::REQUIRED, 'values' => Config::arrayOf(['name' => Config::NAME | Config::REQUIRED, 'value' => Config::ANY, 'deprecationReason' => Config::STRING, 'description' => Config::STRING], Config::KEY_AS_NAME | Config::MAYBE_NAME), 'description' => Config::STRING]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->values = []; if (!empty($config['values'])) { foreach ($config['values'] as $name => $value) { if (!is_array($value)) { if (is_string($name)) { $value = ['name' => $name, 'value' => $value]; } else { if (is_int($name) && is_string($value)) { $value = ['name' => $value, 'value' => $value]; } } } // value will be equal to name only if 'value' is not set in definition $this->values[] = new EnumValueDefinition($value + ['name' => $name, 'value' => $name]); } } }
public function __construct(array $config) { Config::validate($config, ['name' => Config::STRING, 'fields' => Config::arrayOf(FieldDefinition::getDefinition(), Config::KEY_AS_NAME), 'resolveType' => Config::CALLBACK, 'description' => Config::STRING]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->_fields = !empty($config['fields']) ? FieldDefinition::createMap($config['fields']) : []; $this->_resolveTypeFn = isset($config['resolveType']) ? $config['resolveType'] : null; }
/** * InterfaceType constructor. * @param array $config */ public function __construct(array $config) { if (!isset($config['name'])) { $config['name'] = $this->tryInferName(); } Config::validate($config, ['name' => Config::NAME, 'fields' => Config::arrayOf(FieldDefinition::getDefinition(), Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE), 'resolveType' => Config::CALLBACK, 'description' => Config::STRING]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->config = $config; }
/** * InputObjectType constructor. * @param array $config */ public function __construct(array $config) { if (!isset($config['name'])) { $config['name'] = $this->tryInferName(); } Config::validate($config, ['name' => Config::NAME | Config::REQUIRED, 'fields' => Config::arrayOf(['name' => Config::NAME | Config::REQUIRED, 'type' => Config::INPUT_TYPE | Config::REQUIRED, 'defaultValue' => Config::ANY, 'description' => Config::STRING], Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE), 'description' => Config::STRING]); $this->config = $config; $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; }
public function __construct($config) { Config::validate($config, ['name' => Config::STRING | Config::REQUIRED, 'values' => Config::arrayOf(['name' => Config::STRING | Config::REQUIRED, 'value' => Config::ANY, 'deprecationReason' => Config::STRING, 'description' => Config::STRING], Config::KEY_AS_NAME), 'description' => Config::STRING]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->_values = []; if (!empty($config['values'])) { foreach ($config['values'] as $name => $value) { $this->_values[] = Utils::assign(new EnumValueDefinition(), $value + ['name' => $name]); } } }
public function __construct($config) { Config::validate($config, ['name' => Config::STRING | Config::REQUIRED, 'types' => Config::arrayOf(Config::OBJECT_TYPE | Config::REQUIRED), 'resolveType' => Config::CALLBACK, 'description' => Config::STRING]); Utils::invariant(!empty($config['types']), ""); /** * Optionally provide a custom type resolver function. If one is not provided, * the default implemenation will call `isTypeOf` on each implementing * Object type. */ $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->_types = $config['types']; $this->_resolveType = isset($config['resolveType']) ? $config['resolveType'] : null; }
/** * ObjectType constructor. * @param array $config */ public function __construct(array $config) { if (!isset($config['name'])) { $config['name'] = $this->tryInferName(); } Utils::invariant(!empty($config['name']), 'Every type is expected to have name'); // Note: this validation is disabled by default, because it is resource-consuming // TODO: add bin/validate script to check if schema is valid during development Config::validate($config, ['name' => Config::NAME | Config::REQUIRED, 'fields' => Config::arrayOf(FieldDefinition::getDefinition(), Config::KEY_AS_NAME | Config::MAYBE_THUNK | Config::MAYBE_TYPE), 'description' => Config::STRING, 'interfaces' => Config::arrayOf(Config::INTERFACE_TYPE, Config::MAYBE_THUNK), 'isTypeOf' => Config::CALLBACK, 'resolveField' => Config::CALLBACK]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->resolveFieldFn = isset($config['resolveField']) ? $config['resolveField'] : null; $this->config = $config; }
public function __construct(array $config) { Config::validate($config, ['name' => Config::STRING | Config::REQUIRED, 'fields' => Config::arrayOf(FieldDefinition::getDefinition(), Config::KEY_AS_NAME), 'description' => Config::STRING, 'interfaces' => Config::arrayOf(Config::INTERFACE_TYPE), 'isTypeOf' => Config::CALLBACK]); $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; if (isset($config['fields'])) { $this->_fields = FieldDefinition::createMap($config['fields']); } $this->_interfaces = isset($config['interfaces']) ? $config['interfaces'] : []; $this->_isTypeOf = isset($config['isTypeOf']) ? $config['isTypeOf'] : null; if (!empty($this->_interfaces)) { InterfaceType::addImplementationToInterfaces($this, $this->_interfaces); } }
/** * UnionType constructor. * @param $config */ public function __construct($config) { if (!isset($config['name'])) { $config['name'] = $this->tryInferName(); } Config::validate($config, ['name' => Config::NAME | Config::REQUIRED, 'types' => Config::arrayOf(Config::OBJECT_TYPE, Config::MAYBE_THUNK | Config::REQUIRED), 'resolveType' => Config::CALLBACK, 'description' => Config::STRING]); /** * Optionally provide a custom type resolver function. If one is not provided, * the default implemenation will call `isTypeOf` on each implementing * Object type. */ $this->name = $config['name']; $this->description = isset($config['description']) ? $config['description'] : null; $this->config = $config; }
public function testProhibitsPuttingNonObjectTypesInUnions() { $int = Type::int(); $badUnionTypes = [$int, new NonNull($int), new ListOfType($int), $this->interfaceType, $this->unionType, $this->enumType, $this->inputObjectType]; Config::enableValidation(); foreach ($badUnionTypes as $type) { try { new UnionType(['name' => 'BadUnion', 'types' => [$type]]); $this->fail('Expected exception not thrown'); } catch (\Exception $e) { $this->assertSame('Expecting callable or instance of GraphQL\\Type\\Definition\\ObjectType at "types:0", but got "' . get_class($type) . '"', $e->getMessage()); } } Config::disableValidation(); }
/** * @param array|Config $field * @return FieldDefinition */ public static function create($field) { Config::validate($field, self::getDefinition()); return new self($field); }
/** * Late instance initialization */ private function initialize() { if ($this->_initialized) { return; } $config = $this->_config; if (isset($config['fields']) && is_callable($config['fields'])) { $config['fields'] = call_user_func($config['fields']); } if (isset($config['interfaces']) && is_callable($config['interfaces'])) { $config['interfaces'] = call_user_func($config['interfaces']); } // Note: this validation is disabled by default, because it is resource-consuming // TODO: add bin/validate script to check if schema is valid during development Config::validate($this->_config, ['name' => Config::STRING | Config::REQUIRED, 'fields' => Config::arrayOf(FieldDefinition::getDefinition(), Config::KEY_AS_NAME), 'description' => Config::STRING, 'interfaces' => Config::arrayOf(Config::INTERFACE_TYPE), 'isTypeOf' => Config::CALLBACK, 'resolveField' => Config::CALLBACK]); $this->_fields = FieldDefinition::createMap($config['fields']); $this->_interfaces = isset($config['interfaces']) ? $config['interfaces'] : []; $this->_isTypeOf = isset($config['isTypeOf']) ? $config['isTypeOf'] : null; $this->_initialized = true; }
/** * @param array|Config $field * @param string $typeName * @return FieldDefinition */ public static function create($field, $typeName = null) { if ($typeName) { Config::validateField($typeName, $field, self::getDefinition()); } return new self($field); }
// Test this using following command // php -S localhost:8080 ./index.php require_once '../../vendor/autoload.php'; use GraphQL\Examples\Blog\Types; use GraphQL\Examples\Blog\AppContext; use GraphQL\Examples\Blog\Data\DataSource; use GraphQL\Schema; use GraphQL\GraphQL; use GraphQL\Type\Definition\Config; use GraphQL\Error\FormattedError; // Disable default PHP error reporting - we have better one for debug mode (see bellow) ini_set('display_errors', 0); if (!empty($_GET['debug'])) { // Enable additional validation of type configs // (disabled by default because it is costly) Config::enableValidation(); // Catch custom errors (to report them in query results if debugging is enabled) $phpErrors = []; set_error_handler(function ($severity, $message, $file, $line) use(&$phpErrors) { $phpErrors[] = new ErrorException($message, 0, $severity, $file, $line); }); } try { // Initialize our fake data source DataSource::init(); // Prepare context that will be available in all field resolvers (as 3rd argument): $appContext = new AppContext(); $appContext->viewer = DataSource::findUser('1'); // simulated "currently logged-in user" $appContext->rootUrl = 'http://localhost:8080'; $appContext->request = $_REQUEST;
/** * @it prohibits putting non-Object types in unions */ public function testProhibitsPuttingNonObjectTypesInUnions() { $int = Type::int(); $badUnionTypes = [$int, new NonNull($int), new ListOfType($int), $this->interfaceType, $this->unionType, $this->enumType, $this->inputObjectType]; // TODO: extract config validation to separate test Config::enableValidation(); foreach ($badUnionTypes as $type) { try { new UnionType(['name' => 'BadUnion', 'types' => [$type]]); $this->fail('Expected exception not thrown'); } catch (\Exception $e) { $this->assertSame('Error in "BadUnion" type definition: expecting callable or ObjectType definition at "types:0", but got "' . Utils::getVariableType($type) . '"', $e->getMessage()); } } Config::disableValidation(); }