且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Magento更改“自定义选项"值,然后将其添加到购物车

更新时间:2023-11-26 23:14:22

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

The custom options are only stored on the quote as option ID's and values. Every time the options are rendered, they are basically reloaded from the database.
If you modify the values, you would need to save them, and that would set them for everybody.

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

That said, I work around the issue by adding an additional custom option with the modified value on the fly, using an event observer. For this I use additional options.
Then I remove the original custom option from the quote item.

剩下的1.4个Magento会处理剩下的事情,但是从那以后,您需要手动将其他选项复制到订单项中,并且还需要注意,如果对项目进行重新排序,它会再次设置.

Up to 1.4 Magento took care of the rest, but since then you need to copy the additional options to the order item manually, and also need to take care it's set again if an item is reordered.

因此,这是一个示例观察者配置.

So here is an example observer configuration.

<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>

其余的在观察者类中处理.

The rest is handled in the observer class.

/**
 * 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);
        }
    }

简而言之.添加错误检查并照顾特殊情况,例如根据需要再次将同一产品添加到购物车.
希望这可以帮助您开始使用自定义产品选项.熟悉它们后,还算不错.

This is it in a nutshell. Add error checking and taking care of special cases like adding the same product to the cart again as needed.
Hope this gets you started working with custom product options. Not half bad once you get familiar with them.