【问题标题】:Magento - Add product programmatically to cart through observerMagento - 通过观察者以编程方式将产品添加到购物车
【发布时间】:2014-07-01 20:44:11
【问题描述】:

这是我的问题:以编程方式添加产品报价的正确事件是什么(条目 sales_flat_quote_item 表)。此外,我必须从用户/客户那里捕获添加到购物车的项目/产品,因为他们的数据信息将确定将以编程方式添加的产品。所以场景是:

  1. 用户/客户将产品添加到购物车
  2. 为挂钩找到正确的事件
  3. 获取有关添加到购物车的产品的信息
  4. 根据产品 ID 将其他产品添加到购物车并修改其数据

在我看来,最好在将产品写入数据库之前使用报价。

我知道如何通过 Mage_Sales_Model_Quote::_addCatalogProduct() 添加它。但我想通过事件观察者而不是覆盖核心类来做到这一点。

编辑

在帖子中进行了更多研究和建议后,我能够让它工作。对我来说,关键是理解观察者中的对象,它们的类和类方法

var_dump(get_class($quote)); // $item // $product
var_dump(get_class_methods($quote)); // $item // $product

现在知道方法可用,就更容易弄清楚了:

事件:

        <events>
        <checkout_cart_product_add_after>
            <observers>
                <unifiedarts_configurablebundleset>
                    <type>singleton</type>
                    <class>Namespace_ConfigurableBundleSet_Model_Observer</class>
                    <method>salesQuoteEditItems</method>
                </unifiedarts_configurablebundleset>
            </observers>
        </checkout_cart_product_add_after>
    </events>

以及观察者数据:

public function salesQuoteEditItems($observer)
{
    $event = $observer->getEvent();
    $item = $event->getQuoteItem();
    $product = $item->getProduct();
    $quote = $item->getQuote();

    $parent = Mage::getModel('catalog/product')->load($product->getParentProductId());

    if($parent->getTypeId() == 'bundle')
    {

        if($product->getTypeId() == 'configurable')
        {

            if ($simpleItem = $item->getOptionByCode('simple_product'))
            {
                // check if the simple product is in the table
                if(!$quote->hasProductId($simpleItem->getProduct()->getId()))
                {
                    echo '<br /><br /> no simple, add it';
                    echo ' simple id '.$simpleItem->getProduct()->getId();

                    $simple = Mage::getModel('catalog/product')->load($simpleItem->getProduct()->getId());
                    $quoteItem = Mage::getModel('sales/quote_item')->setProduct($simple);
                    $parentItem = ( $item->getParentItem() ? $item->getParentItem() : $item );

                    echo 'simple id '.$simpleItem->getProduct()->getId();

                    $item->setRowWeight($product->getWeight());

                    $quoteItem->setQuote($quote);
                    $quoteItem->setQty('1');
                    $quoteItem->setParentItem($parentItem);
                    $quoteItem->setStoreId(Mage::app()->getStore()->getId());
                    $quoteItem->setOriginalCustomPrice(0);

                    $quote->addItem($quoteItem);
                    $quote->save();

                }
                else
                {
                    echo 'simple found change someting'; die;
                }
            }
        }
    }

}

问题是我的扩展必须在捆绑包中添加一个已配置的项目。产品视图正在运行。艰巨的任务是将它放入购物车。现在,一切正常,直到返回并使用不同的(配置的)选项再次添加产品。

您在上面看到我尝试检查简单产品(我手动添加)。代码在 sales_flat_quote_item 表中生成两个新行。

如何删除旧的两个条目,或者是否有其他更好的方法来设置新数据?谢谢:)

【问题讨论】:

  • 您想在购物车的哪个阶段添加产品?
  • 这就是重点,我不知道添加它的最佳时间是什么时候。我想与添加到购物车的其他产品一起,在我对报价项目进行检查后将其插入到报价对象中

标签: magento events observers


【解决方案1】:

在 config.xml 中声明事件观察者

<events>
            <checkout_cart_product_add_after>
                <observers>
                    <custommodule>
                        <class>custommodule/observer</class>
                        <method>cartProductAddAfter</method>
                    </custommodule>
                </observers>
            </checkout_cart_product_add_after>
            <checkout_cart_product_update_after>
                <observers>
                    <custommodule>
                        <class>custommodule/observer</class>
                        <method>cartProductUpdateAfter</method>
                    </custommodule>
                </observers>
            </checkout_cart_product_update_after>
</events>

开发观察者处理程序

class Vendor_Custommodule_Model_Observer 
{
    /* If you'd like to do the same while updating the shopping cart*/
    public function cartProductUpdateAfter($observer)
    {
        $this->cartProductAddAfter($observer);
    }

    public function cartProductAddAfter($observer)
    {
        $product = $observer->getEvent()->getProduct();
        $currentItem = $observer->getEvent()->getQuoteItem();
        $quote = $currentItem->getQuote();
        $quoteItems = $quote->getItems();

        /* Detect Product ID and Qty programmatically */
        $idToAdd = "ANY PRODUCT ID";
        $qty = 1;

        $productToAdd = Mage::getModel('catalog/product');
        /* @var $productToAdd Mage_Catalog_Model_Product */
        $productToAdd->load($idToAdd);

        $this->_addProductToCart($productToAdd, $qty);
    }

    protected function _addProductToCart($product, $qty)
    {
        $cart = Mage::getSingleton('checkout/cart');
        /* @var $cart Mage_Checkout_Model_Cart */
        if ($product->getId()) {
            $cart->addProduct($product, $qty);
            return true;
        }
        return false;
    }
}

【讨论】:

  • 你的建议帮助了我。使用提供的新信息检查我的编辑
【解决方案2】:

试试这个代码:

<events>
    <checkout_cart_product_add_after>
        <observers>
            <additionalproduct>
                <type>singleton</type>
                <class>YourPackage_YourModule_Model_Observer</class>
                <method>additionalProduct</method>
            </additionalproduct>
        </observers>
    </checkout_cart_product_add_after>
</events>

观察者类代码:

class YourPackage_YourModule_Model_Observer 
{

    public function additionalProduct(Varien_Event_Observer $observer)
    {
        $item = $observer->getQuoteItem(); // current Quote object
        $product = $observer->getProduct(); // current Product object

        // apply your logice here 
        // for example 
        $id = '100'; // Replace id with your product id
        $qty = '2'; // Replace qty with your qty
        $_product = Mage::getModel('catalog/product')->load($id);
        $cart = Mage::getModel('checkout/cart');
        $cart->init();
        $cart->addProduct($_product, array('qty' => $qty));
        $cart->save();
        Mage::getSingleton('checkout/session')->setCartWasUpdated(true);


    }
}

希望对您有所帮助!

【讨论】:

  • 你为什么使用购物车对象而不是报价对象?我假设在您的代码中,产品已经在购物车中。缺少一些东西,例如报价 ID。我需要它将产品添加到相同的报价中
  • 请详细说明您的要求,以便我可以让您知道您可以继续进行的正确事件。谢谢
  • 我编辑了我的帖子,提供更多信息和当前进度,看看
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-09
  • 2015-01-31
  • 1970-01-01
  • 1970-01-01
  • 2015-11-27
相关资源
最近更新 更多