childCollectionFactory = $childCollectionFactory; $this->searchCriteriaBuilder = $searchCriteriaBuilder; $this->metadataPool = $metadataPool; $this->collectionProcessor = $collectionProcessor; $this->collectionPostProcessor = $collectionPostProcessor; } /** * Add parent to collection filter * * @param Product $product * @return void */ public function addParentProduct(Product $product) : void { $linkField = $this->metadataPool->getMetadata(ProductInterface::class)->getLinkField(); $productId = $product->getData($linkField); if (isset($this->parentProducts[$productId])) { return; } if (!empty($this->childrenMap)) { $this->childrenMap = []; } $this->parentProducts[$productId] = $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 * @param ContextInterface $context * @param array $attributeCodes * @return array */ public function getChildProductsByParentId(int $id, ContextInterface $context, array $attributeCodes) : array { $childrenMap = $this->fetch($context, $attributeCodes); if (!isset($childrenMap[$id])) { return []; } return $childrenMap[$id]; } /** * Fetch all children products from parent id's. * * @param ContextInterface $context * @param array $attributeCodes * @return array */ private function fetch(ContextInterface $context, array $attributeCodes) : array { if (empty($this->parentProducts) || !empty($this->childrenMap)) { return $this->childrenMap; } /** @var ChildCollection $childCollection */ $childCollection = $this->childCollectionFactory->create(); foreach ($this->parentProducts as $product) { $childCollection->setProductFilter($product); } $childCollection->addWebsiteFilter($context->getExtensionAttributes()->getStore()->getWebsiteId()); $attributeCodes = array_unique(array_merge($this->attributeCodes, $attributeCodes)); $this->collectionProcessor->process( $childCollection, $this->searchCriteriaBuilder->create(), $attributeCodes, $context ); $this->collectionPostProcessor->process($childCollection, $attributeCodes); /** @var Product $childProduct */ foreach ($childCollection as $childProduct) { if ((int)$childProduct->getStatus() !== Status::STATUS_ENABLED) { continue; } $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; } /** * @inheritDoc */ public function _resetState(): void { $this->parentProducts = []; $this->childrenMap = []; $this->attributeCodes = []; } }