ConfigurableVariant.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. declare(strict_types=1);
  7. namespace Magento\ConfigurableProductGraphQl\Model\Resolver;
  8. use Magento\Framework\GraphQl\Schema\Type\ResolveInfo;
  9. use Magento\Catalog\Api\Data\ProductInterface;
  10. use Magento\Catalog\Model\Product;
  11. use Magento\CatalogGraphQl\Model\Resolver\Products\Attributes\Collection as AttributeCollection;
  12. use Magento\ConfigurableProduct\Model\Product\Type\Configurable as Type;
  13. use Magento\ConfigurableProductGraphQl\Model\Options\Collection as OptionCollection;
  14. use Magento\ConfigurableProductGraphQl\Model\Variant\Collection;
  15. use Magento\Framework\EntityManager\MetadataPool;
  16. use Magento\Framework\GraphQl\Config\Element\Field;
  17. use Magento\Framework\GraphQl\Query\Resolver\ValueFactory;
  18. use Magento\Framework\GraphQl\Query\ResolverInterface;
  19. /**
  20. * @inheritdoc
  21. */
  22. class ConfigurableVariant implements ResolverInterface
  23. {
  24. /**
  25. * @var Collection
  26. */
  27. private $variantCollection;
  28. /**
  29. * @var OptionCollection
  30. */
  31. private $optionCollection;
  32. /**
  33. * @var ValueFactory
  34. */
  35. private $valueFactory;
  36. /**
  37. * @var AttributeCollection
  38. */
  39. private $attributeCollection;
  40. /**
  41. * @var MetadataPool
  42. */
  43. private $metadataPool;
  44. /**
  45. * @param Collection $variantCollection
  46. * @param OptionCollection $optionCollection
  47. * @param ValueFactory $valueFactory
  48. * @param AttributeCollection $attributeCollection
  49. * @param MetadataPool $metadataPool
  50. */
  51. public function __construct(
  52. Collection $variantCollection,
  53. OptionCollection $optionCollection,
  54. ValueFactory $valueFactory,
  55. AttributeCollection $attributeCollection,
  56. MetadataPool $metadataPool
  57. ) {
  58. $this->variantCollection = $variantCollection;
  59. $this->optionCollection = $optionCollection;
  60. $this->valueFactory = $valueFactory;
  61. $this->attributeCollection = $attributeCollection;
  62. $this->metadataPool = $metadataPool;
  63. }
  64. /**
  65. * @inheritdoc
  66. */
  67. public function resolve(Field $field, $context, ResolveInfo $info, array $value = null, array $args = null)
  68. {
  69. $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
  70. if ($value['type_id'] !== Type::TYPE_CODE || !isset($value[$linkField])) {
  71. $result = function () {
  72. return null;
  73. };
  74. return $this->valueFactory->create($result);
  75. }
  76. $this->variantCollection->addParentProduct($value['model']);
  77. $fields = $this->getProductFields($info);
  78. $matchedFields = $this->attributeCollection->getRequestAttributes($fields);
  79. $this->variantCollection->addEavAttributes($matchedFields);
  80. $this->optionCollection->addProductId((int)$value[$linkField]);
  81. $result = function () use ($value, $linkField) {
  82. $children = $this->variantCollection->getChildProductsByParentId((int)$value[$linkField]);
  83. $options = $this->optionCollection->getAttributesByProductId((int)$value[$linkField]);
  84. $variants = [];
  85. /** @var Product $child */
  86. foreach ($children as $key => $child) {
  87. $variants[$key] = ['sku' => $child['sku'], 'product' => $child, 'options' => $options];
  88. }
  89. return $variants;
  90. };
  91. return $this->valueFactory->create($result);
  92. }
  93. /**
  94. * Return field names for all requested product fields.
  95. *
  96. * @param ResolveInfo $info
  97. * @return string[]
  98. */
  99. private function getProductFields(ResolveInfo $info)
  100. {
  101. $fieldNames = [];
  102. foreach ($info->fieldNodes as $node) {
  103. if ($node->name->value !== 'product') {
  104. continue;
  105. }
  106. foreach ($node->selectionSet->selections as $selectionNode) {
  107. $fieldNames[] = $selectionNode->name->value;
  108. }
  109. }
  110. return $fieldNames;
  111. }
  112. }