これはバグであることが判明しました Mage_Sales_Model_Quote_Item::compare()
Magento CE 1.9.2 / EE 1.14.2で導入されことがました。このメソッドは、アイテムを比較して、同じ製品であり、マージできるかどうかを決定するために使用されます(ログイン中およびカートに製品を追加するとき)。
すべてのカスタムオプションを比較するとき、それはrepresantativeないオプション(スキップする_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を適用するか、代わりにクラスの書き換えを使用する必要があります。