原来,这是Mage_Sales_Model_Quote_Item::compare()
Magento CE 1.9.2 / EE 1.14.2中引入的错误。该方法用于比较项目,以确定它们是否是同一产品,并且可以合并(在登录期间以及将产品添加到购物车时)。
比较所有自定义选项时,应跳过非代表性的选项(_notRepresentOptions
),即info_buyRequest选项。
在以前的Magento版本中,它看起来像这样:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
并正常工作。现在看起来像这样:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
以及其他检查是否hasCustomOptions()
导致了所描述的错误。为什么?看起来已经添加了支票,以始终将带有自定义选项的产品分开。我认为这是没有道理的,至少在实施方式上没有意义,但是有一些我不知道的原因。
但是,$item->getProduct()->hasCustomOptions()
对于报价项目,始终返回true!
这是方法:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
而且$this->_customOptions
还包含info_buyRequest
来自报价项目的选项。
对于非干扰性的解决方案,我尝试info_buyRequest
从上的观察者中的所有产品中删除该选项sales_quote_merge_before
,但没有成功。
原因在于Mage_Sales_Model_Quote_Item_Abstract::getProduct()
从报价项目本身再次复制选项:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
解
我为此创建了一个重写,Mage_Sales_Model_Quote_Item
其中有一个替代,getProduct()
以不包括该info_buyRequest
选项:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
这给捆绑产品,下面的替代产品或@AnnaVölkl所述的官方补丁带来了麻烦,是一个更好的解决方案
另类
你也可以删除有问题&& !$item->getProduct()->hasCustomOptions()
的compare()
,如果你反正重写项目模型法。我不知道它试图解决什么问题,但它创造了更多...
更新2016年1月29日
我将此问题报告给了Magento,并得到了他们无法重现该问题的答复,因此该补丁不会将其纳入社区版(提交APPSEC-1321)。
这意味着,如果遇到问题,则需要在每次更新后应用企业补丁SUPEE-6190 或改用类重写。