Collection.php 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  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\Options;
  8. use Magento\Catalog\Api\Data\ProductInterface;
  9. use Magento\Catalog\Model\Product;
  10. use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\CollectionFactory;
  11. use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Attribute\Collection
  12. as AttributeCollection;
  13. use Magento\ConfigurableProduct\Model\Product\Type\Configurable\Attribute;
  14. use Magento\Catalog\Model\ProductFactory;
  15. use Magento\Framework\EntityManager\MetadataPool;
  16. /**
  17. * Collection for fetching options for all configurable options pulled back in result set.
  18. */
  19. class Collection
  20. {
  21. /**
  22. * @var CollectionFactory
  23. */
  24. private $attributeCollectionFactory;
  25. /**
  26. * @var ProductFactory
  27. */
  28. private $productFactory;
  29. /**
  30. * @var MetadataPool
  31. */
  32. private $metadataPool;
  33. /**
  34. * @var int[]
  35. */
  36. private $productIds = [];
  37. /**
  38. * @var array
  39. */
  40. private $attributeMap = [];
  41. /**
  42. * @param CollectionFactory $attributeCollectionFactory
  43. * @param ProductFactory $productFactory
  44. * @param MetadataPool $metadataPool
  45. */
  46. public function __construct(
  47. CollectionFactory $attributeCollectionFactory,
  48. ProductFactory $productFactory,
  49. MetadataPool $metadataPool
  50. ) {
  51. $this->attributeCollectionFactory = $attributeCollectionFactory;
  52. $this->productFactory = $productFactory;
  53. $this->metadataPool = $metadataPool;
  54. }
  55. /**
  56. * Add product id to attribute collection filter.
  57. *
  58. * @param int $productId
  59. */
  60. public function addProductId(int $productId) : void
  61. {
  62. if (!in_array($productId, $this->productIds)) {
  63. $this->productIds[] = $productId;
  64. }
  65. }
  66. /**
  67. * Retrieve attributes for given product id or empty array
  68. *
  69. * @param int $productId
  70. * @return array
  71. */
  72. public function getAttributesByProductId(int $productId) : array
  73. {
  74. $attributes = $this->fetch();
  75. if (!isset($attributes[$productId])) {
  76. return [];
  77. }
  78. return $attributes[$productId];
  79. }
  80. /**
  81. * Fetch attribute data
  82. *
  83. * @return array
  84. */
  85. private function fetch() : array
  86. {
  87. if (empty($this->productIds) || !empty($this->attributeMap)) {
  88. return $this->attributeMap;
  89. }
  90. $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
  91. /** @var AttributeCollection $attributeCollection */
  92. $attributeCollection = $this->attributeCollectionFactory->create();
  93. foreach ($this->productIds as $id) {
  94. /** @var Product $product */
  95. $product = $this->productFactory->create();
  96. $product->setData($linkField, $id);
  97. $attributeCollection->setProductFilter($product);
  98. }
  99. /** @var Attribute $attribute */
  100. foreach ($attributeCollection->getItems() as $attribute) {
  101. $productId = (int)$attribute->getProductId();
  102. if (!isset($this->attributeMap[$productId])) {
  103. $this->attributeMap[$productId] = [];
  104. }
  105. $attributeData = $attribute->getData();
  106. $this->attributeMap[$productId][$attribute->getId()] = $attribute->getData();
  107. $this->attributeMap[$productId][$attribute->getId()]['id'] = $attribute->getId();
  108. $this->attributeMap[$productId][$attribute->getId()]['attribute_code']
  109. = $attribute->getProductAttribute()->getAttributeCode();
  110. $this->attributeMap[$productId][$attribute->getId()]['values'] = $attributeData['options'];
  111. $this->attributeMap[$productId][$attribute->getId()]['label']
  112. = $attribute->getProductAttribute()->getStoreLabel();
  113. }
  114. return $this->attributeMap;
  115. }
  116. }