123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188 |
- <?php
- /**
- * Copyright © Magento, Inc. All rights reserved.
- * See COPYING.txt for license details.
- */
- declare(strict_types=1);
- namespace Magento\ConfigurableProductGraphQl\Model\Variant;
- use Magento\Catalog\Api\Data\ProductInterface;
- use Magento\Catalog\Model\Product;
- use Magento\Catalog\Model\ProductFactory;
- use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\Collection as ChildCollection;
- use Magento\ConfigurableProduct\Model\ResourceModel\Product\Type\Configurable\Product\CollectionFactory;
- use Magento\Framework\EntityManager\MetadataPool;
- use Magento\Framework\Api\SearchCriteriaBuilder;
- use Magento\CatalogGraphQl\Model\Resolver\Products\DataProvider\Product as DataProvider;
- /**
- * Collection for fetching configurable child product data.
- */
- class Collection
- {
- /**
- * @var CollectionFactory
- */
- private $childCollectionFactory;
- /**
- * @var ProductFactory
- */
- private $productFactory;
- /**
- * @var SearchCriteriaBuilder
- */
- private $searchCriteriaBuilder;
- /**
- * @var DataProvider
- */
- private $productDataProvider;
- /**
- * @var MetadataPool
- */
- private $metadataPool;
- /**
- * @var Product[]
- */
- private $parentProducts = [];
- /**
- * @var array
- */
- private $childrenMap = [];
- /**
- * @var string[]
- */
- private $attributeCodes = [];
- /**
- * @param CollectionFactory $childCollectionFactory
- * @param ProductFactory $productFactory
- * @param SearchCriteriaBuilder $searchCriteriaBuilder
- * @param DataProvider $productDataProvider
- * @param MetadataPool $metadataPool
- */
- public function __construct(
- CollectionFactory $childCollectionFactory,
- ProductFactory $productFactory,
- SearchCriteriaBuilder $searchCriteriaBuilder,
- DataProvider $productDataProvider,
- MetadataPool $metadataPool
- ) {
- $this->childCollectionFactory = $childCollectionFactory;
- $this->productFactory = $productFactory;
- $this->searchCriteriaBuilder = $searchCriteriaBuilder;
- $this->productDataProvider = $productDataProvider;
- $this->metadataPool = $metadataPool;
- }
- /**
- * Add parent to collection filter
- *
- * @param Product $product
- * @return void
- */
- public function addParentProduct(Product $product) : void
- {
- if (isset($this->parentProducts[$product->getId()])) {
- return;
- }
- if (!empty($this->childrenMap)) {
- $this->childrenMap = [];
- }
- $this->parentProducts[$product->getId()] = $product;
- }
- /**
- * Add attributes to collection filter
- *
- * @param array $attributeCodes
- * @return void
- */
- public function addEavAttributes(array $attributeCodes) : void
- {
- $this->attributeCodes = array_replace($this->attributeCodes, $attributeCodes);
- }
- /**
- * Retrieve child products from for passed in parent id.
- *
- * @param int $id
- * @return array
- */
- public function getChildProductsByParentId(int $id) : array
- {
- $childrenMap = $this->fetch();
- if (!isset($childrenMap[$id])) {
- return [];
- }
- return $childrenMap[$id];
- }
- /**
- * Fetch all children products from parent id's.
- *
- * @return array
- * @throws \Exception
- */
- private function fetch() : array
- {
- if (empty($this->parentProducts) || !empty($this->childrenMap)) {
- return $this->childrenMap;
- }
- $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField();
- foreach ($this->parentProducts as $product) {
- $attributeData = $this->getAttributesCodes($product);
- /** @var ChildCollection $childCollection */
- $childCollection = $this->childCollectionFactory->create();
- $childCollection->addAttributeToSelect($attributeData);
- /** @var Product $product */
- $product->setData($linkField, $product->getId());
- $childCollection->setProductFilter($product);
- /** @var Product $childProduct */
- foreach ($childCollection->getItems() as $childProduct) {
- $formattedChild = ['model' => $childProduct, 'sku' => $childProduct->getSku()];
- $parentId = (int)$childProduct->getParentId();
- if (!isset($this->childrenMap[$parentId])) {
- $this->childrenMap[$parentId] = [];
- }
- $this->childrenMap[$parentId][] = $formattedChild;
- }
- }
- return $this->childrenMap;
- }
- /**
- * Get attributes code
- *
- * @param \Magento\Catalog\Model\Product $currentProduct
- * @return array
- */
- private function getAttributesCodes(Product $currentProduct): array
- {
- $attributeCodes = [];
- $allowAttributes = $currentProduct->getTypeInstance()->getConfigurableAttributes($currentProduct);
- foreach ($allowAttributes as $attribute) {
- $productAttribute = $attribute->getProductAttribute();
- if (!\in_array($productAttribute->getAttributeCode(), $attributeCodes)) {
- $attributeCodes[] = $productAttribute->getAttributeCode();
- }
- }
- return $attributeCodes;
- }
- }
|