【问题标题】:Magento change Custom Option value before adding it to cartMagento 在将其添加到购物车之前更改自定义选项值
【发布时间】:2012-02-17 19:24:20
【问题描述】:

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

尺寸:小、中、大

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

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

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

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

【问题讨论】:

  • 您是否以某种方式保存了这些额外的数据?当你在后台查看订单时,有没有显示腰围、胸围、长度等?
  • 对不起,如果我不够清楚的话。如果 javascript 在 phtml 文件中硬编码,我只会显示此信息。例如 if(val==small) then show Waist 30, Chest 36, Length 42... 现在我想将此额外信息添加到订单中,以便为每件商品存储。

标签: magento


【解决方案1】:

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

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

【讨论】:

  • 感谢 Vinai 的帮助。我会试试这个。
  • 这里是基于这种方法的另一个答案,但有一点不同,更详细:stackoverflow.com/a/9496266/485589
  • 如果我在 sales_quote_collect_totals_before 中设置添加选项会有帮助。因为我的 sales_convert_quote_item_to_order_item 它没有调用。全部
  • @vinay :愿望清单怎么可能?当用户点击添加到愿望清单按钮时,我们如何在愿望清单上显示这些附加选项
  • 我在 Magento 2 上实现了这个,这样我就可以更改自定义选项值,并且更改会反映在购物车页面上,但是当我关注 Magento2 上的 sales_convert_quote_item_to_order_item 观察者时,这些更改不会反映在订单页面上。
【解决方案2】:

转到Admin -&gt; Catalog -&gt; Attributes -&gt; Manage Attributes。从列表中找到您的属性。在你的情况下,它可能是size。单击它并转到Manage Labels / Options。从那里您可以将附加信息添加到每个值。您可以将标签更改为“Small - Waist 30, Chest 36, Length 42”,并针对要更改的每个属性值重复此操作。

【讨论】:

  • 肖恩,感谢您的回答,但它不是属性,它是自定义选项。不幸的是,我无法遵循此方法,因为还涉及其他问题的日志。如果您能指导我有问题地更改自定义选项的值,那将使我的生活更轻松。
【解决方案3】:

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

Mage_Sales_Model_Quote_Item 中的函数 getItemByProduct 调用函数表示产品,该函数在报价和产品选项之间进行比较。如果两个对象具有相同的选项列表,则返回引用对象,否则返回 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();
        }
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-06
    • 2023-04-02
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多