Magento – 基于用户input引用/订购产品项目属性
概要
我想创build一个不保存到产品的产品属性,或者像普通的产品属性一样显示在产品编辑页面上。 相反,我希望它被保存到订单/报价项目,并显示在订单,发票等。 在将产品添加到购物车之前,还应该由前端的客户configuration。
细节
- 就像使用自定义选项一样 ,表单元素应该被添加到前端产品页面。
- 与自定义选项不同 ,这不是实际的产品属性。 它不应该显示在pipe理产品页面或属性集上。
- 客户需要提供有效的价值。 我需要能够做服务器端validation。
- 我想有一个.phtml模板生成它的HTML。 目前,我可以用满意的(devise)结果覆盖app / design / frontend / base / default / catalog / product / view / type / default.phtml 。 但是我不知道如何捕捉,validation并最终保存它的价值。
- 这个表单元素的值应该与quote / order产品项一起保存。
- 此值应显示在任何和所有发票,订单,销售电子邮件中。
- 我想用模板控制输出,或者至less能够返回用于显示值的string
我的问题
- 当产品被添加到购物车时,如何validation并最终将前端产品页面上
<input>
的值保存到报价项目中,然后在结算过程中将订单项目保存到订单项目中? - 如何在订单,发票,销售电子邮件和此类网页上显示此值?
- 如何过滤订单集合以获取具有我的值设置为特定值的项目的订单?
更新1
我发现我可以在一个catalog/product
模型(也可能是sales/quote_item
)上运行这个代码,在sales_quote_item_qty_set_after
$infoBuyRequest = $product->getCustomOption('info_buyRequest'); $buyRequest = new Varien_Object(unserialize($infoBuyRequest->getValue())); $myData = $buyRequest->getMyData();
通过这种方式,我能够从产品页面上的<input>
检索自定义客户提供的数据。
我怀疑这个info_buyRequest
保存与报价和订单项目。 如果是这样,这部分解决了我的问题1和2.但是,我仍然不知道在哪里适合运行此代码,我不知道如何显示它在后端的订单/报价/报告页面。 因为这是存储在数据库中的序列化值,所以根据我的自定义数据来获取报价/订单项目集合将是非常困难的。
Magento提供了添加非产品属性或产品定制选项的选项的function。 它们在产品上设置,并使用选项代码additional_options
报价项目。
有两个步骤你需要采取,每个可以通过事件观察员处理。 如果您希望额外的选项进行重新sorting,您还需要观察第三个事件。
将选项添加到报价项目
第一步是在添加到购物车之前添加事件观察者以在装载的产品上设置附加选项。 一种select是使用catalog_product_load_after
事件。
<catalog_product_load_after> <observers> <extra_options> <type>model</type> <class>extra_options/observer</class> <method>catalogProductLoadAfter</method> </extra_options> </observers> </catalog_product_load_after>
在事件观察员,你可以添加额外的检查,请求的页面确实是一个添加到购物车的行动。 此观察者方法的要点是将select的特殊选项additional_options
到产品模型的additional_options
选项。
public function catalogProductLoadAfter(Varien_Event_Observer $observer) { // set the additional options on the product $action = Mage::app()->getFrontController()->getAction(); if ($action->getFullActionName() == 'checkout_cart_add') { // assuming you are posting your custom form values in an array called extra_options... if ($options = $action->getRequest()->getParam('extra_options')) { $product = $observer->getProduct(); // add to the additional options array $additionalOptions = array(); if ($additionalOption = $product->getCustomOption('additional_options')) { $additionalOptions = (array) unserialize($additionalOption->getValue()); } foreach ($options as $key => $value) { $additionalOptions[] = array( 'label' => $key, 'value' => $value, ); } // add the additional options array with the option code additional_options $observer->getProduct() ->addCustomOption('additional_options', serialize($additionalOptions)); } } }
附加选项将自动从产品移至报价项目。 有了这个观察员,你的select将出现在购物车和结帐审查。
添加选项以订购商品
为了让他们坚持下来,需要一个额外的观察员(只有自Magento 1.5以来)。
<sales_convert_quote_item_to_order_item> <observers> <extra_options> <type>model</type> <class>extra_options/observer</class> <method>salesConvertQuoteItemToOrderItem</method> </extra_options> </observers> </sales_convert_quote_item_to_order_item>
在这里,我们将选项从报价项目移动到订单项目。
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); } }
从这一点起,附加选项将显示在客户订单历史logging的前端和订单电子邮件中,以及pipe理界面订单视图,发票,发货,信用卡和PDF中。
添加支持重新sorting
为了在再次订购期间把这些新订单交给新订单,您需要注意将其复制。 这是使用checkout_cart_product_add_after
事件的一种可能性。
<checkout_cart_product_add_after> <observers> <extra_options> <type>singleton</type> <class>extra_options/observer</class> <method>checkoutCartProductAddAfter</method> </extra_options> </observers> </checkout_cart_product_add_after>
额外选项的parsing和构build额外的选项数组应该被移到一个单独的函数中,以避免代码重复,但是在这个例子中,为了清楚起见,我将为每个方法留下所需的逻辑。
public function checkoutCartProductAddAfter(Varien_Event_Observer $observer) { $action = Mage::app()->getFrontController()->getAction(); if ($action->getFullActionName() == 'sales_order_reorder') { $item = $observer->getQuoteItem(); $buyInfo = $item->getBuyRequest(); if ($options = $buyInfo->getExtraOptions()) { $additionalOptions = array(); if ($additionalOption = $item->getOptionByCode('additional_options')) { $additionalOptions = (array) unserialize($additionalOption->getValue()); } foreach ($options as $key => $value) { $additionalOptions[] = array( 'label' => $key, 'value' => $value, ); } $item->addOption(array( 'code' => 'additional_options', 'value' => serialize($additionalOptions) )); } } }
翻译:
没有机制来转换这些选项标签或值。 以下是在这方面可能有用的一些想法。
在quote_item_load_after事件观察者中,获取额外的选项数组并设置$option['print_value'] = $helper->__($option['value']);
。 如果设置了print_value
,Magento将使用它来渲染显示。
订单项也可以做同样的事情。
没有print_label
这样的东西,但是你可以设置一个自定义的索引( label_source
也许),并使用该标签作为源代码,例如$option['label'] = $helper->__($option['label_source']);
。
除此之外,您可能不得不诉诸修改模板(grep for getItemOptions()
),或者覆盖块类(grep additional_options
)。
可以将自定义字段添加到报价项目。 如何为 Magento中的订单行项目添加自定义字段以便开始。 我最近使用这些指令来添加一个自定义字段到一个Magento报价项目,这个概念是好的,但是在那篇文章中有一些不太好的做法。 事情我会做不同的事情:
- 使用安装脚本将字段添加到数据库,而不是直接执行。
- 使用Magento的Request对象而不是直接访问$ _REQUEST。
- 使用扩展和重写,而不是修改Magento核心。
- 从扩展中对config.xml进行更改,而不是修改内核。
一般来说,最好避免修改Magento核心,并通过模块应用您的定制,因为它将使升级变得更容易/可能。 如果在moduleCreator可以帮助您生成必要的样板之前尚未创build自己的扩展。
我的解决scheme在Magento 1.8
设置选项报价项目
$quoteItem = $cart->getQuote()->getItemById($itemId); $quoteItem->addOption(array('label' => 'buymode', 'code' => 'buymode', 'value' => $data['buymode'])); $quoteItem->save();
从QuoteItem访问选项
$quoteItem->getOptionByCode('buymode')->getValue();
将选项转移到OrderItem
注册事件sales_convert_quote_item_to_order_item
public function onConvertQuoteItemToOrderItem($observer) { $orderItem = $observer->getOrderItem(); $quoteItem = $observer->getItem(); $options = $orderItem->getProductOptions(); $options['buymode'] = $quoteItem->getOptionByCode('buymode')->getValue(); $orderItem->setProductOptions($options); }
来自OrderItem的访问选项
$orderItem->getProductOptionByCode('buymode')