Magento 在观察者中重新计算购物车总数

发布于 2024-12-08 04:51:03 字数 1674 浏览 0 评论 0 原文

我有一个观察者,如果商品缺货(即客户每隔 x 次返回购物车,并且购物车中的商品已缺货),则会从购物车中删除商品,并向用户显示一条消息。

删除商品有效,但更新购物车总数无效。任何帮助将不胜感激!

我的观察者观察 sales_quote_save_before 事件:

public function checkStockStatus($observer)
{
    // return if disabled or observer already executed on this request
    if (!Mage::helper('stockcheck')->isEnabled() || Mage::registry('stockcheck_observer_executed')) {
        return $this;
    }

    $quote = $observer->getEvent()->getQuote();
    $outOfStockCount = 0;

    foreach ($quote->getAllItems() as $item) {
        $product = Mage::getModel('catalog/product')->load($item->getProductId());
        $stockItem = $product->getStockItem();
        if ($stockItem->getIsInStock()) {
            // in stock - for testing only
            $this->_getSession()->addSuccess(Mage::helper('stockcheck')->__('in stock'));
            $item->setData('calculation_price', null);
            $item->setData('original_price', null);
        }
        else {
            //remove item 
            $this->_getCart()->removeItem($item->getId());
            $outOfStockCount++; 
            $this->_getSession()->addError(Mage::helper('stockcheck')->__('Out of Stock'));
        }
    }

    if ($outOfStockCount) > 0) {       
        $quote->setTotalsCollectedFlag(false)->collectTotals();
    } 

    Mage::register('stockcheck_observer_executed', true);

    return $this;         
}

protected function _getCart()
{
    return Mage::getSingleton('checkout/cart');
}

protected function _getSession()
{
    return Mage::getSingleton('checkout/session');
}  

I have an observer that removes items from the cart if they are out of stock (i.e. customer returns to their cart ofter x time, and an item in the cart has gone out of stock), and shows a message to the user.

Removing the item(s) works, but updating the cart total does not. Any help would be much appreciated!

My observer observes the sales_quote_save_before event:

public function checkStockStatus($observer)
{
    // return if disabled or observer already executed on this request
    if (!Mage::helper('stockcheck')->isEnabled() || Mage::registry('stockcheck_observer_executed')) {
        return $this;
    }

    $quote = $observer->getEvent()->getQuote();
    $outOfStockCount = 0;

    foreach ($quote->getAllItems() as $item) {
        $product = Mage::getModel('catalog/product')->load($item->getProductId());
        $stockItem = $product->getStockItem();
        if ($stockItem->getIsInStock()) {
            // in stock - for testing only
            $this->_getSession()->addSuccess(Mage::helper('stockcheck')->__('in stock'));
            $item->setData('calculation_price', null);
            $item->setData('original_price', null);
        }
        else {
            //remove item 
            $this->_getCart()->removeItem($item->getId());
            $outOfStockCount++; 
            $this->_getSession()->addError(Mage::helper('stockcheck')->__('Out of Stock'));
        }
    }

    if ($outOfStockCount) > 0) {       
        $quote->setTotalsCollectedFlag(false)->collectTotals();
    } 

    Mage::register('stockcheck_observer_executed', true);

    return $this;         
}

protected function _getCart()
{
    return Mage::getSingleton('checkout/cart');
}

protected function _getSession()
{
    return Mage::getSingleton('checkout/session');
}  

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

北笙凉宸 2024-12-15 04:51:03

当天提示:通过观察*_save_after并尝试强制同一对象发生更改
通常会再次调用保存,并且最终会陷入无限循环 .oO

但是,如果您观察 quote 类中的collectTotals() 方法,那么您会发现您丢失了一个重要的标志 ->setTotalsCollectedFlag(false)->collectTotals() 使得一旦计算完成就可以进行计算。

如果您的荣耀之路上没有一些错误,生活将会有所不同,因此请注意 Magento 中的以下问题:问题#26145

Tip for the day: by observing the *_save_after and trying to force the same object to change
will normally call save again and you will end up in endless loop .oO

However if you observe the collectTotals() method in quote class then you'll notice that you are missing a important flag ->setTotalsCollectedFlag(false)->collectTotals() to make the calculation possible once it has been already calculated.

Life would be something different if there were not some bugs in your path to glory so be aware of the following issue in Magento: Issue #26145

雅心素梦 2024-12-15 04:51:03

谢谢@Anton 的帮助!

最终对我有用的答案是在重定向之前(在观察者中)调用 session_write_close();

if (// products are out-of-stock and were removed...) {
    $this->_getSession()->addError('Error message here.');
    $this->_getSession()->getQuote()->setTotalsCollectedFlag(false)->collectTotals();
    session_write_close();
    Mage::app()->getResponse()->setRedirect('index');
}

Thank you @Anton for your help!

The answer that ended up working for me was to make a call to session_write_close(); before the redirect (in the observer):

if (// products are out-of-stock and were removed...) {
    $this->_getSession()->addError('Error message here.');
    $this->_getSession()->getQuote()->setTotalsCollectedFlag(false)->collectTotals();
    session_write_close();
    Mage::app()->getResponse()->setRedirect('index');
}
阳光下慵懒的猫 2024-12-15 04:51:03

下一个流程怎么样:

  1. sales_quote_save_before 上删除观察者中的项目,并向注册表添加一些标志:Mage::register('ooops_we_need_a_redirect', $url)

  2. sales_quote_save_after 上的观察者中,如果需要,请进行重定向:

    if (Mage::registry('ooops_we_need_a_redirect')) {
    // 进行重定向
    }

What about next flow:

  1. Remove items in observer on sales_quote_save_before and add some flag to registry: Mage::register('ooops_we_need_a_redirect', $url)

  2. In observer on sales_quote_save_after do redirect if needed:

    if (Mage::registry('ooops_we_need_a_redirect')) {
    // do redirect
    }

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文