cancel
Showing results for 
Search instead for 
Did you mean: 

Add child of configurable product to cart

SOLVED

Add child of configurable product to cart

I'm sure I'm missing something. I want to show each size of my product as a child of a configurable product; each size is a simple product. I would like the child product to be added to the cart; not the configurable product with the configuration.

 

For example, I want it to look like the bottom one; not the top one.configvssimple.jpg

 

Is this simple change? I can't seem to figure it out.

1 ACCEPTED SOLUTION

Accepted Solutions

Re: Add child of configurable product to cart

SR/MagentoStackExchange/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Controller\Cart\Add">
        <plugin name="SR_MagentoStackExchange::add_child_to_cart" type="SR\MagentoStackExchange\Plugin\Checkout\Controller\Cart\Add" sortOrder="1"/>
    </type>
</config>

SR/MagentoStackExchange/Plugin/Checkout/Controller/Cart/Add.php

<?php
namespace SR\MagentoStackExchange\Plugin\Checkout\Controller\Cart;

use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;

class Add
{
    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var Configurable
     */
    private $configurable;

    /**
     * Add constructor.
     *
     * @param StoreManagerInterface $storeManager
     * @param ProductRepositoryInterface $productRepository
     * @param Configurable $configurable
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        ProductRepositoryInterface $productRepository,
        Configurable $configurable
    ) {
        $this->productRepository = $productRepository;
        $this->storeManager = $storeManager;
        $this->configurable = $configurable;
    }

    public function aroundExecute(
        \Magento\Checkout\Controller\Cart\Add $subject,
        \Closure $proceed
    ) {

        $productId = (int)$subject->getRequest()->getParam('product');
        if ($product = $this->initProduct($productId)) {
            if ($product->getTypeId() == Configurable::TYPE_CODE) {
                $params = $subject->getRequest()->getParams();
                $childProduct = $this->configurable->getProductByAttributes($params['super_attribute'], $product);
                if ($childProduct->getId()) {
                    $params['product'] = $childProduct->getId();
                    $subject->getRequest()->setParams($params);
                }
            }
        }

        return $proceed();
    }

    /**
     * Initialize product instance from request data
     *
     * @return \Magento\Catalog\Model\Product|false
     */
    protected function initProduct($productId)
    {
        if ($productId) {
            $storeId = $this->storeManager->getStore()->getId();
            try {
                return $this->productRepository->getById($productId, false, $storeId);
            } catch (NoSuchEntityException $e) {
                return false;
            }
        }
        return false;
    }
}
-----
If Issue Solved, Click Kudos and Accept As solutions.
Sohel Rana, 7x Magento 2, 2x Magento 1 Certified

View solution in original post

4 REPLIES 4

Re: Add child of configurable product to cart

SR/MagentoStackExchange/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\Checkout\Controller\Cart\Add">
        <plugin name="SR_MagentoStackExchange::add_child_to_cart" type="SR\MagentoStackExchange\Plugin\Checkout\Controller\Cart\Add" sortOrder="1"/>
    </type>
</config>

SR/MagentoStackExchange/Plugin/Checkout/Controller/Cart/Add.php

<?php
namespace SR\MagentoStackExchange\Plugin\Checkout\Controller\Cart;

use Magento\Store\Model\StoreManagerInterface;
use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\Framework\Exception\NoSuchEntityException;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;

class Add
{
    /**
     * @var StoreManagerInterface
     */
    private $storeManager;

    /**
     * @var ProductRepositoryInterface
     */
    private $productRepository;

    /**
     * @var Configurable
     */
    private $configurable;

    /**
     * Add constructor.
     *
     * @param StoreManagerInterface $storeManager
     * @param ProductRepositoryInterface $productRepository
     * @param Configurable $configurable
     */
    public function __construct(
        StoreManagerInterface $storeManager,
        ProductRepositoryInterface $productRepository,
        Configurable $configurable
    ) {
        $this->productRepository = $productRepository;
        $this->storeManager = $storeManager;
        $this->configurable = $configurable;
    }

    public function aroundExecute(
        \Magento\Checkout\Controller\Cart\Add $subject,
        \Closure $proceed
    ) {

        $productId = (int)$subject->getRequest()->getParam('product');
        if ($product = $this->initProduct($productId)) {
            if ($product->getTypeId() == Configurable::TYPE_CODE) {
                $params = $subject->getRequest()->getParams();
                $childProduct = $this->configurable->getProductByAttributes($params['super_attribute'], $product);
                if ($childProduct->getId()) {
                    $params['product'] = $childProduct->getId();
                    $subject->getRequest()->setParams($params);
                }
            }
        }

        return $proceed();
    }

    /**
     * Initialize product instance from request data
     *
     * @return \Magento\Catalog\Model\Product|false
     */
    protected function initProduct($productId)
    {
        if ($productId) {
            $storeId = $this->storeManager->getStore()->getId();
            try {
                return $this->productRepository->getById($productId, false, $storeId);
            } catch (NoSuchEntityException $e) {
                return false;
            }
        }
        return false;
    }
}
-----
If Issue Solved, Click Kudos and Accept As solutions.
Sohel Rana, 7x Magento 2, 2x Magento 1 Certified

Re: Add child of configurable product to cart

Its not a simple change, You need to customization for it to working child as main item in cart page for the configurable product.

 

Check the addProduct() function from Cart.php file of Checkout module, https://github.com/magento/magento2/blob/5916c5a0c3eb595ace91448c35a170924cd1c4e1/app/code/Magento/C...

 

If Issue Solved, Click Kudos/Accept As solutions. Get Magento insight from
Magento 2 Blogs/Tutorial

Re: Add child of configurable product to cart

@Sohel That works well for the main shopping cart, but does screw up my minicart. Thanks for the plugin though. I should be able to figure out some from there.

Re: Add child of configurable product to cart

This works fairly well for me.

It changes the name of the configurable item in the minicart and cart to the simple product selected.

However, the product doesn't link to the listing anymore.

Is there any way to have the simple product in the minicart and cart to link to the configurable listing?