Magento 在将其添加到购物车之前更改自定义选项值

问题描述 投票:0回答:3

我在 Magento 中为我的产品设置了一个自定义选项作为下拉菜单,即

尺寸:小号、中号、大号

在产品页面上,我使用 javascript 显示每个选项的附加信息。

小号 - 腰围 30,胸围 36,长度 42...
中码 - 腰围 32,胸围 38,长度 44...
大号 - 腰围 34,胸围 40,长度 48...

当我将产品添加到购物车时,我会在购物车中看到尺寸标题(小号、中号或大号),但我还想显示此附加信息(腰围 30、胸围 36、长度 42...)并将其与订单一起保存。

最好的方法是什么?预先感谢。

php magento
3个回答
30
投票

自定义选项仅作为选项 ID 和值存储在报价中。每次渲染选项时,它们基本上都是从数据库中重新加载的。
如果修改这些值,则需要保存它们,这将为每个人设置它们。

也就是说,我通过使用事件观察器添加一个带有动态修改值的附加自定义选项来解决这个问题。为此,我使用了附加选项。
然后我从报价项中删除原始自定义选项。

直到 1.4 Magento 才处理剩下的事情,但从那时起,您需要手动将附加选项复制到订单项目,并且还需要注意如果重新订购项目,则需要重新设置它。

这是一个观察者配置示例。

<frontend>
    <events>
        <checkout_cart_product_add_after>
            <observers>
                <customoptions>
                    <type>singleton</type>
                    <class>customoptions/observer</class>
                    <method>checkoutCartProductAddAfter</method>
                </customoptions>
            </observers>
        </checkout_cart_product_add_after>
        <sales_convert_quote_item_to_order_item>
            <observers>
                <customoptions>
                    <type>singleton</type>
                    <class>customoptions/observer</class>
                    <method>salesConvertQuoteItemToOrderItem</method>
                </customoptions>
            </observers>
        </sales_convert_quote_item_to_order_item>
    </events>
</frontend>

剩下的事情在观察者类中处理。

/**
 * Add additional options to order item product options (this is missing in the core)
 *
 * @param Varien_Event_Observer $observer
 */
public function salesConvertQuoteItemToOrderItem(Varien_Event_Observer $observer)
{
    $quoteItem = $observer->getItem();
    if ($additionalOptions = $quoteItem->getOptionByCode('additional_options')) {
        $orderItem = $observer->getOrderItem();
        $options = $orderItem->getProductOptions();
        $options['additional_options'] = unserialize($additionalOptions->getValue());
        $orderItem->setProductOptions($options);
    }
}

/**
 * Manipulate the custom product options
 *
 * @param Varien_Event_Observer $observer
 * @return void
 */
public function checkoutCartProductAddAfter(Varien_Event_Observer $observer)
{
    $item = $observer->getQuoteItem();
    $infoArr = array();

    if ($info = $item->getProduct()->getCustomOption('info_buyRequest')) {
        $infoArr = unserialize($info->getValue());
    }

    // Set additional options in case of a reorder
    if ($infoArr && isset($infoArr['additional_options'])) {
        // An additional options array is set on the buy request - this is a reorder
        $item->addOption(array(
            'code' => 'additional_options',
            'value' => serialize($infoArr['additional_options'])
        ));
        return;
    }

    $options = Mage::helper('catalog/product_configuration')->getCustomOptions($item);

    foreach ($options as $option)
    {
        // The only way to identify a custom option without
        // hardcoding ID's is the label :-(
        // But manipulating options this way is hackish anyway
        if ('Size' === $option['label'])
        {
            $optId = $option['option_id'];

            // Add replacement custom option with modified value
            $additionalOptions = array(array(
                'code' => 'my_code',
                'label' => $option['label'],
                'value' => $option['value'] . ' YOUR EXTRA TEXT',
                'print_value' => $option['print_value'] . ' YOUR EXTRA TEXT',
            ));
            $item->addOption(array(
                'code' => 'additional_options',
                'value' => serialize($additionalOptions),
            ));

            // Update info_buyRequest to reflect changes
            if ($infoArr &&
                isset($infoArr['options']) &&
                isset($infoArr['options'][$optId]))
               {
                // Remove real custom option
                unset($infoArr['options'][$optId]);

                // Add replacement additional option for reorder (see above)
                $infoArr['additional_options'] = $additionalOptions;

                $info->setValue(serialize($infoArr));
                $item->addOption($info);
            }

            // Remove real custom option id from option_ids list
            if ($optionIdsOption = $item->getProduct()->getCustomOption('option_ids')) {
                $optionIds = explode(',', $optionIdsOption->getValue());
                if (false !== ($idx = array_search($optId, $optionIds))) {
                    unset($optionIds[$idx]);
                    $optionIdsOption->setValue(implode(',', $optionIds));
                    $item->addOption($optionIdsOption);
                }
            }

            // Remove real custom option
            $item->removeOption('option_' . $optId);
        }
    }

简而言之,就是这样。添加错误检查并处理特殊情况,例如根据需要再次将相同的产品添加到购物车。
希望这能让您开始使用自定义产品选项。一旦你熟悉了它们,还不错。


0
投票

转到

Admin -> Catalog -> Attributes -> Manage Attributes
。从列表中找到您的属性。就您而言,可能是
size
。单击它并转到
Manage Labels / Options
。从那里您可以向每个值添加附加信息。您可以将标签更改为“小 - 腰围 30、胸围 36、长度 42”,并对要更改的每个属性值重复此操作。


-1
投票

只是为 Vinai 的出色解决方案添加一个小修复。 该解决方案打破了按产品获取报价项目的逻辑。

Mage_Sales_Model_Quote_Item 中的函数 getItemByProduct 调用函数representProduct,该函数在报价和产品选项之间进行比较。如果两个对象具有相同的选项列表,则返回引用对象,否则返回 false。

因为现在我们添加了自定义选项,两个对象都有不同的选项,所以该函数将返回 false。

解决此问题的一种方法是重写 Mage_Sales_Model_Quote_Item 类 并将您的自定义选项代码添加到构造函数中的局部变量 $_notRepresentOptions 中。

class Custom_Options_Model_Sales_Quote_Item extends Mage_Sales_Model_Quote_Item {

        /**
         * Initialize resource model
         *
         */
        protected function _construct()
        {        
            $this->_notRepresentOptions = array_merge($this->_notRepresentOptions, array('additional_options'));

           parent::_construct();
        }
}
© www.soinside.com 2019 - 2024. All rights reserved.