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; } }