diff --git a/app/code/Magento/GraphQl/Controller/GraphQl.php b/app/code/Magento/GraphQl/Controller/GraphQl.php
index c4a0b55de9bf..c04bb7f5775a 100644
--- a/app/code/Magento/GraphQl/Controller/GraphQl.php
+++ b/app/code/Magento/GraphQl/Controller/GraphQl.php
@@ -111,10 +111,10 @@ public function dispatch(RequestInterface $request) : ResponseInterface
$data = $this->jsonSerializer->unserialize($request->getContent());
$query = isset($data['query']) ? $data['query'] : '';
-
+ $variables = isset($data['variables']) ? $data['variables'] : null;
// We have to extract queried field names to avoid instantiation of non necessary fields in webonyx schema
// Temporal coupling is required for performance optimization
- $this->queryFields->setQuery($query);
+ $this->queryFields->setQuery($query, $variables);
$schema = $this->schemaGenerator->generate();
$result = $this->queryProcessor->process(
diff --git a/app/code/Magento/GraphQl/etc/di.xml b/app/code/Magento/GraphQl/etc/di.xml
index b2083ea758e5..6acb78f9c7f9 100644
--- a/app/code/Magento/GraphQl/etc/di.xml
+++ b/app/code/Magento/GraphQl/etc/di.xml
@@ -27,7 +27,7 @@
- Magento\Framework\GraphQl\Config\Element\InterfaceFactory
- Magento\Framework\GraphQl\Config\Element\TypeFactory
- - Magento\Framework\GraphQl\Config\Element\TypeFactory
+ - Magento\Framework\GraphQl\Config\Element\InputFactory
- Magento\Framework\GraphQl\Config\Element\EnumFactory
@@ -55,24 +55,16 @@
-
+
-
+
- Magento\Framework\GraphQl\Schema\Type\Output\OutputTypeObject
+ - Magento\Framework\GraphQl\Schema\Type\Input\InputObjectType
- Magento\Framework\GraphQl\Schema\Type\Output\OutputInterfaceObject
- Magento\Framework\GraphQl\Schema\Type\Enum\Enum
-
-
-
- - Magento\Framework\GraphQl\Schema\Type\Input\InputObjectType
- - Magento\Framework\GraphQl\Schema\Type\Input\InputObjectType
- - Magento\Framework\GraphQl\Schema\Type\Enum\Enum
-
-
-
Magento\Framework\GraphQl\Schema\Type\Output\ElementMapper\FormatterComposite
diff --git a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php
index 5458b5cfbb73..add0510c6b40 100644
--- a/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php
+++ b/dev/tests/api-functional/framework/Magento/TestFramework/TestCase/GraphQl/Client.php
@@ -57,8 +57,8 @@ public function postQuery(string $query, array $variables = [], string $operatio
$headers = array_merge($headers, ['Accept: application/json', 'Content-Type: application/json']);
$requestArray = [
'query' => $query,
- 'variables' => empty($variables) ? $variables : null,
- 'operationName' => empty($operationName) ? $operationName : null
+ 'variables' => !empty($variables) ? $variables : null,
+ 'operationName' => !empty($operationName) ? $operationName : null
];
$postData = $this->json->jsonEncode($requestArray);
diff --git a/dev/tests/api-functional/testsuite/Magento/GraphQl/VariablesSupportQueryTest.php b/dev/tests/api-functional/testsuite/Magento/GraphQl/VariablesSupportQueryTest.php
new file mode 100644
index 000000000000..7448b165fc23
--- /dev/null
+++ b/dev/tests/api-functional/testsuite/Magento/GraphQl/VariablesSupportQueryTest.php
@@ -0,0 +1,81 @@
+productRepository = Bootstrap::getObjectManager()->get(ProductRepositoryInterface::class);
+ }
+
+ /**
+ * @magentoApiDataFixture Magento/Catalog/_files/products_list.php
+ */
+ public function testQueryObjectVariablesSupport()
+ {
+ $productSku = 'simple-249';
+ $minPrice = 153;
+
+ $query
+ = <<<'QUERY'
+query GetProductsQuery($pageSize: Int, $filterInput: ProductFilterInput, $priceSort: SortEnum) {
+ products(
+ pageSize: $pageSize
+ filter: $filterInput
+ sort: {price: $priceSort}
+ ) {
+ items {
+ sku
+ price {
+ minimalPrice {
+ amount {
+ value
+ currency
+ }
+ }
+ }
+ }
+ }
+}
+QUERY;
+
+ $variables = [
+ 'pageSize' => 1,
+ 'priceSort' => 'ASC',
+ 'filterInput' => [
+ 'min_price' => [
+ 'gt' => 150,
+ ],
+ ],
+ ];
+
+ $response = $this->graphQlQuery($query, $variables);
+ /** @var \Magento\Catalog\Model\Product $product */
+ $product = $this->productRepository->get($productSku, false, null, true);
+
+ self::assertArrayHasKey('products', $response);
+ self::assertArrayHasKey('items', $response['products']);
+ self::assertEquals(1, count($response['products']['items']));
+ self::assertArrayHasKey(0, $response['products']['items']);
+ self::assertEquals($product->getSku(), $response['products']['items'][0]['sku']);
+ self::assertEquals(
+ $minPrice,
+ $response['products']['items'][0]['price']['minimalPrice']['amount']['value']
+ );
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config.php b/lib/internal/Magento/Framework/GraphQl/Config.php
index 75b6c64e9d24..ec22b742b1d6 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config.php
@@ -48,12 +48,7 @@ public function __construct(
}
/**
- * Get a data object with data pertaining to a GraphQL type's structural makeup.
- *
- * @param string $configElementName
- * @return ConfigElementInterface
- * @throws \LogicException
- * @SuppressWarnings(PHPMD.UnusedLocalVariable)
+ * @inheritdoc
*/
public function getConfigElement(string $configElementName) : ConfigElementInterface
{
@@ -67,7 +62,7 @@ public function getConfigElement(string $configElementName) : ConfigElementInter
$fieldsInQuery = $this->queryFields->getFieldsUsedInQuery();
if (isset($data['fields'])) {
if (!empty($fieldsInQuery)) {
- foreach ($data['fields'] as $fieldName => $fieldConfig) {
+ foreach (array_keys($data['fields']) as $fieldName) {
if (!isset($fieldsInQuery[$fieldName])) {
unset($data['fields'][$fieldName]);
}
@@ -81,18 +76,20 @@ public function getConfigElement(string $configElementName) : ConfigElementInter
}
/**
- * Return all type names declared in a GraphQL schema's configuration.
- *
- * @return string[]
+ * @inheritdoc
*/
- public function getDeclaredTypeNames() : array
+ public function getDeclaredTypes() : array
{
$types = [];
foreach ($this->configData->get(null) as $item) {
- if (isset($item['type']) && $item['type'] == 'graphql_type') {
- $types[] = $item['name'];
+ if (isset($item['type'])) {
+ $types[] = [
+ 'name' => $item['name'],
+ 'type' => $item['type'],
+ ];
}
}
+
return $types;
}
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Enum.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Enum.php
index b1210e986b77..994ae489af12 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Enum.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Enum.php
@@ -37,7 +37,7 @@ class Enum implements ConfigElementInterface
public function __construct(
string $name,
array $values,
- string $description = ""
+ string $description
) {
$this->name = $name;
$this->values = $values;
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldsFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldsFactory.php
new file mode 100644
index 000000000000..ca6b67eac3d8
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/FieldsFactory.php
@@ -0,0 +1,62 @@
+argumentFactory = $argumentFactory;
+ $this->fieldFactory = $fieldFactory;
+ }
+
+ /**
+ * Create a fields object from a configured array with optional arguments.
+ *
+ * Field data must contain name and type. Other values are optional and include required, itemType, description,
+ * and resolver. Arguments array must be in the format of [$argumentData['name'] => $argumentData].
+ *
+ * @param array $fieldsData
+ * @return Field[]
+ */
+ public function createFromConfigData(
+ array $fieldsData
+ ) : array {
+ $fields = [];
+ foreach ($fieldsData as $fieldData) {
+ $arguments = [];
+ foreach ($fieldData['arguments'] as $argumentData) {
+ $arguments[$argumentData['name']] = $this->argumentFactory->createFromConfigData($argumentData);
+ }
+ $fields[$fieldData['name']] = $this->fieldFactory->createFromConfigData(
+ $fieldData,
+ $arguments
+ );
+ }
+ return $fields;
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Input.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Input.php
new file mode 100644
index 000000000000..8e86f701672c
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Input.php
@@ -0,0 +1,74 @@
+name = $name;
+ $this->fields = $fields;
+ $this->description = $description;
+ }
+
+ /**
+ * Get the type name.
+ *
+ * @return string
+ */
+ public function getName(): string
+ {
+ return $this->name;
+ }
+
+ /**
+ * Get a list of fields that make up the possible return or input values of a type.
+ *
+ * @return Field[]
+ */
+ public function getFields(): array
+ {
+ return $this->fields;
+ }
+
+ /**
+ * Get a human-readable description of the type.
+ *
+ * @return string
+ */
+ public function getDescription(): string
+ {
+ return $this->description;
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/InputFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/InputFactory.php
new file mode 100644
index 000000000000..0e7ccb831a5a
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/InputFactory.php
@@ -0,0 +1,79 @@
+objectManager = $objectManager;
+ $this->fieldsFactory = $fieldsFactory;
+ }
+
+ /**
+ * Instantiate an object representing 'input' GraphQL config element.
+ *
+ * @param array $data
+ * @return ConfigElementInterface
+ */
+ public function createFromConfigData(array $data): ConfigElementInterface
+ {
+ $fields = isset($data['fields']) ? $this->fieldsFactory->createFromConfigData($data['fields']) : [];
+
+ return $this->create(
+ $data,
+ $fields
+ );
+ }
+
+ /**
+ * Create input type object based off array of configured GraphQL InputType data.
+ *
+ * Type data must contain name and the type's fields. Optional data includes description.
+ *
+ * @param array $typeData
+ * @param array $fields
+ * @return Input
+ */
+ private function create(
+ array $typeData,
+ array $fields
+ ): Input {
+ return $this->objectManager->create(
+ Input::class,
+ [
+ 'name' => $typeData['name'],
+ 'fields' => $fields,
+ 'description' => isset($typeData['description']) ? $typeData['description'] : ''
+ ]
+ );
+ }
+}
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/InterfaceType.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/InterfaceType.php
index 320199c14a6d..73ebd42acfb2 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config/Element/InterfaceType.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/InterfaceType.php
@@ -8,7 +8,7 @@
namespace Magento\Framework\GraphQl\Config\Element;
/**
- * Describes the configured data for a GraphQL interface type.
+ * Class representing 'interface' GraphQL config element.
*/
class InterfaceType implements TypeInterface
{
@@ -42,7 +42,7 @@ public function __construct(
string $name,
string $typeResolver,
array $fields,
- string $description = ""
+ string $description
) {
$this->name = $name;
$this->fields = $fields;
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
index 24ff439db034..20d017cc7106 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/Type.php
@@ -8,7 +8,7 @@
namespace Magento\Framework\GraphQl\Config\Element;
/**
- * Describes all the configured data of an Output or Input type in GraphQL.
+ * Class representing 'type' GraphQL config element.
*/
class Type implements TypeInterface
{
diff --git a/lib/internal/Magento/Framework/GraphQl/Config/Element/TypeFactory.php b/lib/internal/Magento/Framework/GraphQl/Config/Element/TypeFactory.php
index c5f3187b0484..5dd477a05089 100644
--- a/lib/internal/Magento/Framework/GraphQl/Config/Element/TypeFactory.php
+++ b/lib/internal/Magento/Framework/GraphQl/Config/Element/TypeFactory.php
@@ -22,28 +22,20 @@ class TypeFactory implements ConfigElementFactoryInterface
private $objectManager;
/**
- * @var ArgumentFactory
+ * @var FieldsFactory
*/
- private $argumentFactory;
-
- /**
- * @var FieldFactory
- */
- private $fieldFactory;
+ private $fieldsFactory;
/**
* @param ObjectManagerInterface $objectManager
- * @param ArgumentFactory $argumentFactory
- * @param FieldFactory $fieldFactory
+ * @param FieldsFactory $fieldsFactory
*/
public function __construct(
ObjectManagerInterface $objectManager,
- ArgumentFactory $argumentFactory,
- FieldFactory $fieldFactory
+ FieldsFactory $fieldsFactory
) {
$this->objectManager = $objectManager;
- $this->argumentFactory = $argumentFactory;
- $this->fieldFactory = $fieldFactory;
+ $this->fieldsFactory = $fieldsFactory;
}
/**
@@ -54,18 +46,8 @@ public function __construct(
*/
public function createFromConfigData(array $data): ConfigElementInterface
{
- $fields = [];
- $data['fields'] = isset($data['fields']) ? $data['fields'] : [];
- foreach ($data['fields'] as $field) {
- $arguments = [];
- foreach ($field['arguments'] as $argument) {
- $arguments[$argument['name']] = $this->argumentFactory->createFromConfigData($argument);
- }
- $fields[$field['name']] = $this->fieldFactory->createFromConfigData(
- $field,
- $arguments
- );
- }
+ $fields = isset($data['fields']) ? $this->fieldsFactory->createFromConfigData($data['fields']) : [];
+
return $this->create(
$data,
$fields
@@ -73,10 +55,10 @@ public function createFromConfigData(array $data): ConfigElementInterface
}
/**
- * Create type object based off array of configured GraphQL Output/InputType data.
+ * Create type object based off array of configured GraphQL Type data.
*
* Type data must contain name and the type's fields. Optional data includes 'implements' (i.e. the interfaces
- * implemented by the types), and description. An InputType cannot implement an interface.
+ * implemented by the types), and description.
*
* @param array $typeData
* @param array $fields
diff --git a/lib/internal/Magento/Framework/GraphQl/ConfigInterface.php b/lib/internal/Magento/Framework/GraphQl/ConfigInterface.php
index c2670967f1db..f7d6cf49e180 100644
--- a/lib/internal/Magento/Framework/GraphQl/ConfigInterface.php
+++ b/lib/internal/Magento/Framework/GraphQl/ConfigInterface.php
@@ -25,9 +25,11 @@ interface ConfigInterface
public function getConfigElement(string $configElementName) : ConfigElementInterface;
/**
- * Return all type names from a GraphQL schema's configuration.
+ * Return all type names declared in a GraphQL schema's configuration and their type.
*
- * @return string[]
+ * Format is ['name' => 'example value', 'type' = 'example value']
+ *
+ * @return array $types
*/
- public function getDeclaredTypeNames() : array;
+ public function getDeclaredTypes() : array;
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Fields.php b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php
index d0bc9591265e..ae1d8d68d5bc 100644
--- a/lib/internal/Magento/Framework/GraphQl/Query/Fields.php
+++ b/lib/internal/Magento/Framework/GraphQl/Query/Fields.php
@@ -24,9 +24,11 @@ class Fields
* Set Query for extracting list of fields.
*
* @param string $query
+ * @param array|null $variables
+ *
* @return void
*/
- public function setQuery($query)
+ public function setQuery($query, array $variables = null)
{
$queryFields = [];
try {
@@ -41,6 +43,9 @@ public function setQuery($query)
]
]
);
+ if (isset($variables)) {
+ $queryFields = array_merge($queryFields, $this->extractVariables($variables));
+ }
} catch (\Exception $e) {
// If a syntax error is encountered do not collect fields
}
@@ -62,4 +67,24 @@ public function getFieldsUsedInQuery()
{
return $this->fieldsUsedInQuery;
}
+
+ /**
+ * Extract and return list of all used fields in GraphQL query's variables
+ *
+ * @param array $variables
+ *
+ * @return string[]
+ */
+ private function extractVariables(array $variables): array
+ {
+ $fields = [];
+ foreach ($variables as $key => $value) {
+ if (is_array($value)){
+ $fields = array_merge($fields, $this->extractVariables($value));
+ }
+ $fields[$key] = $key;
+ }
+
+ return $fields;
+ }
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/FieldEntityAttributesPool.php b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/FieldEntityAttributesPool.php
index e7d14a81b9de..bd9de206ccda 100644
--- a/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/FieldEntityAttributesPool.php
+++ b/lib/internal/Magento/Framework/GraphQl/Query/Resolver/Argument/FieldEntityAttributesPool.php
@@ -38,7 +38,7 @@ public function getEntityAttributesForEntityFromField(string $fieldName) : array
if (isset($this->attributesInstances[$fieldName])) {
return $this->attributesInstances[$fieldName]->getEntityAttributes();
} else {
- throw new \LogicException(sprintf('There is no attrribute class assigned to field %1', $fieldName));
+ throw new \LogicException(sprintf('There is no attribute class assigned to field %1', $fieldName));
}
}
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/SchemaGenerator.php b/lib/internal/Magento/Framework/GraphQl/Schema/SchemaGenerator.php
index 63fef73186b1..250b80defa6d 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/SchemaGenerator.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/SchemaGenerator.php
@@ -8,9 +8,8 @@
namespace Magento\Framework\GraphQl\Schema;
use Magento\Framework\GraphQl\ConfigInterface;
-use Magento\Framework\GraphQl\Schema\SchemaGeneratorInterface;
-use Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper;
use Magento\Framework\GraphQl\Schema;
+use Magento\Framework\GraphQl\Schema\Type\TypeRegistry;
use Magento\Framework\GraphQl\SchemaFactory;
/**
@@ -24,47 +23,46 @@ class SchemaGenerator implements SchemaGeneratorInterface
private $schemaFactory;
/**
- * @var OutputMapper
+ * @var ConfigInterface
*/
- private $outputMapper;
+ private $config;
/**
- * @var ConfigInterface
+ * @var TypeRegistry
*/
- private $config;
+ private $typeRegistry;
/**
* @param SchemaFactory $schemaFactory
- * @param OutputMapper $outputMapper
* @param ConfigInterface $config
+ * @param TypeRegistry $typeRegistry
*/
public function __construct(
SchemaFactory $schemaFactory,
- OutputMapper $outputMapper,
- ConfigInterface $config
+ ConfigInterface $config,
+ TypeRegistry $typeRegistry
) {
$this->schemaFactory = $schemaFactory;
- $this->outputMapper = $outputMapper;
$this->config = $config;
+ $this->typeRegistry = $typeRegistry;
}
/**
- * {@inheritdoc}
+ * @inheritdoc
*/
public function generate() : Schema
{
$schema = $this->schemaFactory->create(
[
- 'query' => $this->outputMapper->getOutputType('Query'),
- 'mutation' => $this->outputMapper->getOutputType('Mutation'),
+ 'query' => $this->typeRegistry->get('Query'),
+ 'mutation' => $this->typeRegistry->get('Mutation'),
'typeLoader' => function ($name) {
- return $this->outputMapper->getOutputType($name);
+ return $this->typeRegistry->get($name);
},
'types' => function () {
- //all types should be generated only on introspection
$typesImplementors = [];
- foreach ($this->config->getDeclaredTypeNames() as $name) {
- $typesImplementors [] = $this->outputMapper->getOutputType($name);
+ foreach ($this->config->getDeclaredTypes() as $type) {
+ $typesImplementors [] = $this->typeRegistry->get($type['name']);
}
return $typesImplementors;
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputFactory.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputFactory.php
deleted file mode 100644
index cbbd97cfdb8c..000000000000
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputFactory.php
+++ /dev/null
@@ -1,60 +0,0 @@
-objectManager = $objectManager;
- $this->prototypes = $prototypes;
- }
-
- /**
- * @param ConfigElementInterface $configElement
- * @return InputTypeInterface
- */
- public function create(ConfigElementInterface $configElement) : InputTypeInterface
- {
- if (!isset($this->typeRegistry[$configElement->getName()])) {
- $this->typeRegistry[$configElement->getName()] =
- $this->objectManager->create(
- $this->prototypes[get_class($configElement)],
- [
- 'configElement' => $configElement
- ]
- );
- }
- return $this->typeRegistry[$configElement->getName()];
- }
-}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputMapper.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputMapper.php
index d806c0b3e68a..d1f48dada2cb 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputMapper.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputMapper.php
@@ -9,27 +9,15 @@
use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor;
use Magento\Framework\GraphQl\Config\Element\Argument;
-use Magento\Framework\GraphQl\ConfigInterface;
+use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ScalarTypes;
-use Magento\Framework\GraphQl\Schema\TypeFactory;
+use Magento\Framework\GraphQl\Schema\Type\TypeRegistry;
+/**
+ * Prepare argument's metadata for GraphQL schema generation
+ */
class InputMapper
{
- /**
- * @var InputFactory
- */
- private $inputFactory;
-
- /**
- * @var ConfigInterface
- */
- private $config;
-
- /**
- * @var TypeFactory
- */
- private $typeFactory;
-
/**
* @var ScalarTypes
*/
@@ -41,24 +29,23 @@ class InputMapper
private $wrappedTypeProcessor;
/**
- * @param InputFactory $inputFactory
- * @param ConfigInterface $config
- * @param TypeFactory $typeFactory
+ * @var TypeRegistry
+ */
+ private $typeRegistry;
+
+ /**
* @param ScalarTypes $scalarTypes
* @param WrappedTypeProcessor $wrappedTypeProcessor
+ * @param TypeRegistry $typeRegistry
*/
public function __construct(
- InputFactory $inputFactory,
- ConfigInterface $config,
- TypeFactory $typeFactory,
ScalarTypes $scalarTypes,
- WrappedTypeProcessor $wrappedTypeProcessor
+ WrappedTypeProcessor $wrappedTypeProcessor,
+ TypeRegistry $typeRegistry
) {
- $this->inputFactory = $inputFactory;
- $this->config = $config;
- $this->typeFactory = $typeFactory;
$this->scalarTypes = $scalarTypes;
$this->wrappedTypeProcessor = $wrappedTypeProcessor;
+ $this->typeRegistry = $typeRegistry;
}
/**
@@ -66,6 +53,7 @@ public function __construct(
*
* @param Argument $argument
* @return array
+ * @throws GraphQlInputException
*/
public function getRepresentation(Argument $argument) : array
{
@@ -73,8 +61,7 @@ public function getRepresentation(Argument $argument) : array
if ($this->scalarTypes->isScalarType($typeName)) {
$instance = $this->wrappedTypeProcessor->processScalarWrappedType($argument);
} else {
- $configElement = $this->config->getConfigElement($typeName);
- $instance = $this->inputFactory->create($configElement);
+ $instance = $this->typeRegistry->get($typeName);
$instance = $this->wrappedTypeProcessor->processWrappedType($argument, $instance);
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputObjectType.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputObjectType.php
index ae2d07ade2ad..fa0327f79bc6 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputObjectType.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Input/InputObjectType.php
@@ -8,21 +8,16 @@
namespace Magento\Framework\GraphQl\Schema\Type\Input;
use Magento\Framework\GraphQl\Config\Data\WrappedTypeProcessor;
-use Magento\Framework\GraphQl\Config\Element\Type as TypeConfigElement;
-use Magento\Framework\GraphQl\ConfigInterface;
+use Magento\Framework\GraphQl\Config\Element\Input as InputConfigElement;
+use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\GraphQl\Schema\Type\ScalarTypes;
-use Magento\Framework\GraphQl\Schema\TypeFactory;
+use Magento\Framework\GraphQl\Schema\Type\TypeRegistry;
/**
* Class InputObjectType
*/
class InputObjectType extends \Magento\Framework\GraphQl\Schema\Type\InputObjectType
{
- /**
- * @var TypeFactory
- */
- private $typeFactory;
-
/**
* @var ScalarTypes
*/
@@ -34,36 +29,27 @@ class InputObjectType extends \Magento\Framework\GraphQl\Schema\Type\InputObject
private $wrappedTypeProcessor;
/**
- * @var InputFactory
+ * @var TypeRegistry
*/
- private $inputFactory;
+ private $typeRegistry;
/**
- * @var ConfigInterface
- */
- public $graphQlConfig;
-
- /**
- * @param TypeConfigElement $configElement
- * @param TypeFactory $typeFactory
+ * @param InputConfigElement $configElement
* @param ScalarTypes $scalarTypes
* @param WrappedTypeProcessor $wrappedTypeProcessor
- * @param InputFactory $inputFactory
- * @param ConfigInterface $graphQlConfig
+ * @param TypeRegistry $typeRegistry
+ * @throws GraphQlInputException
*/
public function __construct(
- TypeConfigElement $configElement,
- TypeFactory $typeFactory,
+ InputConfigElement $configElement,
ScalarTypes $scalarTypes,
WrappedTypeProcessor $wrappedTypeProcessor,
- InputFactory $inputFactory,
- ConfigInterface $graphQlConfig
+ TypeRegistry $typeRegistry
) {
- $this->typeFactory = $typeFactory;
$this->scalarTypes = $scalarTypes;
$this->wrappedTypeProcessor = $wrappedTypeProcessor;
- $this->inputFactory = $inputFactory;
- $this->graphQlConfig = $graphQlConfig;
+ $this->typeRegistry = $typeRegistry;
+
$config = [
'name' => $configElement->getName(),
'description' => $configElement->getDescription()
@@ -75,8 +61,7 @@ public function __construct(
if ($field->getTypeName() == $configElement->getName()) {
$type = $this;
} else {
- $fieldConfigElement = $this->graphQlConfig->getConfigElement($field->getTypeName());
- $type = $this->inputFactory->create($fieldConfigElement);
+ $type = $this->typeRegistry->get($field->getTypeName());
}
$type = $this->wrappedTypeProcessor->processWrappedType($field, $type);
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
index b54cd4d8ca21..034a5702090d 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/ElementMapper/Formatter/Fields.php
@@ -16,7 +16,6 @@
use Magento\Framework\GraphQl\Schema\Type\Output\OutputMapper;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
use Magento\Framework\GraphQl\Schema\Type\ScalarTypes;
-use Magento\Framework\GraphQl\Schema\TypeFactory;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\GraphQl\Schema\Type\ResolveInfoFactory;
@@ -40,11 +39,6 @@ class Fields implements FormatterInterface
*/
private $inputMapper;
- /**
- * @var TypeFactory
- */
- private $typeFactory;
-
/**
* @var ScalarTypes
*/
@@ -64,7 +58,6 @@ class Fields implements FormatterInterface
* @param ObjectManagerInterface $objectManager
* @param OutputMapper $outputMapper
* @param InputMapper $inputMapper
- * @param TypeFactory $typeFactory
* @param ScalarTypes $scalarTypes
* @param WrappedTypeProcessor $wrappedTypeProcessor
* @param ResolveInfoFactory $resolveInfoFactory
@@ -73,7 +66,6 @@ public function __construct(
ObjectManagerInterface $objectManager,
OutputMapper $outputMapper,
InputMapper $inputMapper,
- TypeFactory $typeFactory,
ScalarTypes $scalarTypes,
WrappedTypeProcessor $wrappedTypeProcessor,
ResolveInfoFactory $resolveInfoFactory
@@ -81,14 +73,13 @@ public function __construct(
$this->objectManager = $objectManager;
$this->outputMapper = $outputMapper;
$this->inputMapper = $inputMapper;
- $this->typeFactory = $typeFactory;
$this->scalarTypes = $scalarTypes;
$this->wrappedTypeProcessor = $wrappedTypeProcessor;
$this->resolveInfoFactory = $resolveInfoFactory;
}
/**
- * {@inheritDoc}
+ * @inheritdoc
*/
public function format(TypeInterface $configElement, OutputTypeInterface $outputType): array
{
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputFactory.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputFactory.php
deleted file mode 100644
index 81dad11774b0..000000000000
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputFactory.php
+++ /dev/null
@@ -1,65 +0,0 @@
-objectManager = $objectManager;
- $this->prototypes = $prototypes;
- }
-
- /**
- * Create output type.
- *
- * @param ConfigElementInterface $configElement
- * @return OutputTypeInterface
- */
- public function create(ConfigElementInterface $configElement) : OutputTypeInterface
- {
- if (!isset($this->typeRegistry[$configElement->getName()])) {
- $this->typeRegistry[$configElement->getName()] =
- $this->objectManager->create(
- $this->prototypes[get_class($configElement)],
- [
- 'configElement' => $configElement
- ]
- );
- }
- return $this->typeRegistry[$configElement->getName()];
- }
-}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
index b7f4b8a1f60d..046eeb5b1f93 100644
--- a/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/Output/OutputMapper.php
@@ -7,50 +7,28 @@
namespace Magento\Framework\GraphQl\Schema\Type\Output;
-use Magento\Framework\GraphQl\ConfigInterface;
use Magento\Framework\GraphQl\Schema\Type\OutputTypeInterface;
-use Magento\Framework\GraphQl\Schema\TypeFactory;
+use Magento\Framework\GraphQl\Schema\Type\TypeRegistry;
use Magento\Framework\GraphQl\Exception\GraphQlInputException;
use Magento\Framework\Phrase;
/**
- * Map type names to their output type/interface classes.
+ * Map type names to their output type/interface/enum classes.
*/
class OutputMapper
{
/**
- * @var OutputFactory
+ * @var TypeRegistry
*/
- private $outputFactory;
+ private $typeRegistry;
/**
- * @var OutputTypeInterface[]
- */
- private $outputTypes;
-
- /**
- * @var TypeFactory
- */
- private $typeFactory;
-
- /**
- * @var ConfigInterface
- */
- private $config;
-
- /**
- * @param OutputFactory $outputFactory
- * @param TypeFactory $typeFactory
- * @param ConfigInterface $config
+ * @param TypeRegistry $typeRegistry
*/
public function __construct(
- OutputFactory $outputFactory,
- TypeFactory $typeFactory,
- ConfigInterface $config
+ TypeRegistry $typeRegistry
) {
- $this->outputFactory = $outputFactory;
- $this->config = $config;
- $this->typeFactory = $typeFactory;
+ $this->typeRegistry = $typeRegistry;
}
/**
@@ -62,16 +40,13 @@ public function __construct(
*/
public function getOutputType($typeName)
{
- if (!isset($this->outputTypes[$typeName])) {
- $configElement = $this->config->getConfigElement($typeName);
- $this->outputTypes[$typeName] = $this->outputFactory->create($configElement);
- if (!($this->outputTypes[$typeName] instanceof OutputTypeInterface)) {
- throw new GraphQlInputException(
- new Phrase("Type '{$typeName}' was requested but is not declared in the GraphQL schema.")
- );
- }
- }
+ $outputType = $this->typeRegistry->get($typeName);
- return $this->outputTypes[$typeName];
+ if (!$outputType instanceof OutputTypeInterface) {
+ throw new GraphQlInputException(
+ new Phrase("Type '{$typeName}' was requested but is not declared in the GraphQL schema.")
+ );
+ }
+ return $outputType;
}
}
diff --git a/lib/internal/Magento/Framework/GraphQl/Schema/Type/TypeRegistry.php b/lib/internal/Magento/Framework/GraphQl/Schema/Type/TypeRegistry.php
new file mode 100644
index 000000000000..cde8b6b3e446
--- /dev/null
+++ b/lib/internal/Magento/Framework/GraphQl/Schema/Type/TypeRegistry.php
@@ -0,0 +1,95 @@
+objectManager = $objectManager;
+ $this->config = $config;
+ $this->configToTypeMap = $configToTypeMap;
+ }
+
+ /**
+ * Get GraphQL type object by type name
+ *
+ * @param string $typeName
+ * @return TypeInterface|InputTypeInterface|OutputTypeInterface
+ * @throws GraphQlInputException
+ */
+ public function get(string $typeName): TypeInterface
+ {
+ if (!isset($this->types[$typeName])) {
+ $configElement = $this->config->getConfigElement($typeName);
+
+ $configElementClass = get_class($configElement);
+ if (!isset($this->configToTypeMap[$configElementClass])) {
+ throw new GraphQlInputException(
+ new Phrase(
+ "No mapping to Webonyx type is declared for '%1' config element type.",
+ [$configElementClass]
+ )
+ );
+ }
+
+ $this->types[$typeName] = $this->objectManager->create(
+ $this->configToTypeMap[$configElementClass],
+ [
+ 'configElement' => $configElement,
+ ]
+ );
+
+ if (!($this->types[$typeName] instanceof TypeInterface)) {
+ throw new GraphQlInputException(
+ new Phrase("Type '{$typeName}' was requested but is not declared in the GraphQL schema.")
+ );
+ }
+ }
+ return $this->types[$typeName];
+ }
+}