Magento change Custom Option value before adding it to cart

前端 未结 3 671
眼角桃花
眼角桃花 2020-12-13 22:44

I have setup a custom option for my product in Magento as dropdown i.e.

Size : Small, Medium, Large

On product page I show additional information for each op

3条回答
  •  死守一世寂寞
    2020-12-13 23:19

    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.

    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.

    
        
            
                
                    
                        singleton
                        customoptions/observer
                        checkoutCartProductAddAfter
                    
                
            
            
                
                    
                        singleton
                        customoptions/observer
                        salesConvertQuoteItemToOrderItem
                    
                
            
        
    
    

    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.

提交回复
热议问题