4

I need to display some custom attribute from children product in checkout, I study for long time to come out a stupid solution

  1. Override Magento\Swatches\Block\Product\Renderer\Configurable
  2. Inject productRepository
  3. Get children product directly from productRepository

    $currentProduct = $this->getProduct();
    $childrenIds = $currentProduct->getTypeInstance()->getChildrenIds($currentProduct->getId());
    
    $childrenProducts = [];
    foreach ($childrenIds[0] as $childrenId) {
        $childrenProduct = $this->productRepository->getById($childrenId);
        $childrenProducts[] = $childrenProduct->getData()['customexxxx'];
    
    }
    

Anyone know a smart way to do it ?

1

2 Answers 2

6

You have to just keep below code inside block file and call function inside your template,

protected $productFactory;
protected $dataObjectHelper;
protected $productRepository;

public function __construct(        
    \Magento\Framework\View\Element\Template\Context $context,                   
    \Magento\Catalog\Api\Data\ProductInterfaceFactory $productFactory,  
    \Magento\Catalog\Api\ProductRepositoryInterface $productRepository,    
    \Magento\Framework\Api\DataObjectHelper $dataObjectHelper,
    array $data = [] 
){      
    $this->productFactory = $productFactory;      
    $this->productRepository = $productRepository;        
    $this->dataObjectHelper = $dataObjectHelper;
    parent::__construct($context,$data);    
}


     public function getConfigChildProductIds($id){
            $product = array();
            if(is_numeric($id)){           
                $product = $this->productRepository->getById($id); 
            }else{
                return;
            } 

            if(!isset($product)){
                return;
            }

            if ($product->getTypeId() != \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) {
                return [];
            }

            $storeId = $this->_storeManager->getStore()->getId();

            $productTypeInstance = $product->getTypeInstance();
            $productTypeInstance->setStoreFilter($storeId, $product);
            $usedProducts = $productTypeInstance->getUsedProducts($product);
            $childrenList = [];       

            foreach ($usedProducts  as $child) {
                $attributes = [];
                $isSaleable = $child->isSaleable();

                //getting in-stock product
                if($isSaleable){
                    foreach ($child->getAttributes() as $attribute) {
                        $attrCode = $attribute->getAttributeCode();
                        $value = $child->getDataUsingMethod($attrCode) ?: $child->getData($attrCode);
                        if (null !== $value && $attrCode != 'entity_id') {
                            $attributes[$attrCode] = $value;
                        }
                    }

                    $attributes['store_id'] = $child->getStoreId();
                    $attributes['id'] = $child->getId();
                    /** @var \Magento\Catalog\Api\Data\ProductInterface $productDataObject */
                    $productDataObject = $this->productFactory->create();
                    $this->dataObjectHelper->populateWithArray(
                        $productDataObject,
                        $attributes,
                        '\Magento\Catalog\Api\Data\ProductInterface'
                    );
                    $childrenList[] = $productDataObject;
                }
            }

            $childData = array();
            foreach($childrenList as $child){
                $childData[] = $child;
            }

            return $childData;
        }

Inside template file call ,

 $productId = 10 //parent product id..
 $childObj = $block->getConfigChildProductIds($productId);
    foreach ($childObj as $child){                 
       $getChildId[] = $child->getData();
    }
    echo "<pre>";print_r($getChildId);
2
1

Note that the answer to this question isn't necessarily the correct one. Although the output seems to work, it's not really the Magento 2-way on doing this. First of, use service contracts to get the child products of a configurable. A good example can be found in my answer to this question: https://magento.stackexchange.com/a/155252/2030

Secondly, since you're now set with data models, not inheritance-based models, you need to use the getCustomAttribute()-method to get non-default product attributes. For example:

$attribute = $productModel->getCustomAttribute('foo');
echo $attribute->getValue();

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.