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

时间:2012-02-17 19:24:21

标签: magento

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

尺寸:小,中,大

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

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

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

最好的办法是什么?提前谢谢。

3 个答案:

答案 0 :(得分:29)

自定义选项仅作为选项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);
        }
    }

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

答案 1 :(得分:0)

转到Admin -> Catalog -> Attributes -> Manage Attributes。从列表中找到您的属性。在你的情况下,它可能是size。点击它,然后转到Manage Labels / Options。从那里,您可以将附加信息添加到每个值。您可以将标签更改为“小 - 腰30,胸围36,长度42”,并为要更改的每个属性值重复。

答案 2 :(得分:-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();
        }
}