2

Before add to cart, how to get the simple product of configurable product which would be added?

Notice the Before, because I need compare the simple product attribute with products already in cart to decide whether to add it to shopping cart.

In the core CartController - addAction, it has the parent configurable product $product = $this->_initProduct(); and super_attribute in $params['super_attribute'], I guess use both could get the child simple product, but doesn't find a way after many attempts.

Anyone could give a help? Thanks.

2 Answers 2

3

After a research, finally I found the function getProductByAttributes in app/code/core/Mage/Catalog/Model/Product/Type/Configurable.php, use it could get the child simple product like below.

$childProduct = Mage::getModel('catalog/product_type_configurable')->getProductByAttributes($params['super_attribute'], $product);

The function getProductByAttributes could use a reference when need write similar function, so I will show it here for future reference.

/**
 * Retrieve used product by attribute values
 *  $attrbutesInfo = array(
 *      $attributeId => $attributeValue
 *  )
 *
 * @param  array $attributesInfo
 * @param  Mage_Catalog_Model_Product $product
 * @return Mage_Catalog_Model_Product|null
 */
public function getProductByAttributes($attributesInfo, $product = null)
{
    if (is_array($attributesInfo) && !empty($attributesInfo)) {
        $productCollection = $this->getUsedProductCollection($product)->addAttributeToSelect('name');
        foreach ($attributesInfo as $attributeId => $attributeValue) {
            $productCollection->addAttributeToFilter($attributeId, $attributeValue);
        }
        $productObject = $productCollection->getFirstItem();
        if ($productObject->getId()) {
            return $productObject;
        }

        foreach ($this->getUsedProducts(null, $product) as $productObject) {
            $checkRes = true;
            foreach ($attributesInfo as $attributeId => $attributeValue) {
                $code = $this->getAttributeById($attributeId, $product)->getAttributeCode();
                if ($productObject->getData($code) != $attributeValue) {
                    $checkRes = false;
                }
            }
            if ($checkRes) {
                return $productObject;
            }
        }
    }
    return null;
}
0

Create events.xml at app\code\Vendor\Extension\etc\

<?xml version="1.0"?> 
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Event/etc/events.xsd">
 <event name="checkout_cart_product_add_after">
 <observer name="checkout_cart_after" instance="Vendor\Extension\Observer\Cart\AddtocartbeforeObserver" />
  </event> 
  </config>

Create AddtocartbeforeObserver.php at app/code/Vendor/Extension/Observer/Cart/

<?php
namespace Vendor\Extension\Observer\Cart;

use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
class AddtocartbeforeObserver implements ObserverInterface
{
    public function __construct(
    Configurable $configurableproduct,
        \Magento\Framework\App\RequestInterface $request
    )
        {
    $this->configurableproduct = $configurableproduct;
        $this->request = $request;
        }
    

    public function execute(\Magento\Framework\Event\Observer $observer)
    {
        $item = $observer->getEvent()->getData('quote_item');  
         $product = $observer->getEvent()->getData('product');  
        $productData = $this->request->getParams();
    
    if ($product->getTypeId() == \Magento\ConfigurableProduct\Model\Product\Type\Configurable::TYPE_CODE) 
        {
            $attributes = $productData['super_attribute'];
            $simple_product = $this->configurableproduct->getProductByAttributes($attributes, $product);
           // echo $simple_product->getId();

        }
    }
}

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.