Ternyata ini adalah bug Mage_Sales_Model_Quote_Item::compare()
yang diperkenalkan di Magento CE 1.9.2 / EE 1.14.2. Metode ini digunakan untuk membandingkan item untuk memutuskan apakah mereka adalah produk yang sama dan dapat digabung (saat login dan ketika menambahkan produk ke troli).
Saat membandingkan semua opsi khusus, itu harus melewati opsi yang tidak representantatif ( _notRepresentOptions
), yaitu opsi info_buyRequest .
Dalam versi Magento sebelumnya, tampilannya seperti ini:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
dan bekerja dengan benar. Sekarang terlihat seperti ini:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
dan pemeriksaan tambahan untuk hasCustomOptions()
penyebab bug yang dijelaskan. Mengapa? Sepertinya cek telah ditambahkan untuk selalu menjaga produk dengan opsi khusus terpisah. Saya pikir itu tidak masuk akal, paling tidak dalam cara penerapannya, tetapi akan ada beberapa alasan untuk itu yang tidak saya sadari.
Namun, $item->getProduct()->hasCustomOptions()
selalu kembali benar untuk item kutipan!
Inilah metodenya:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
Tetapi $this->_customOptions
juga berisi info_buyRequest
opsi dari item kutipan.
Untuk solusi yang tidak mengganggu, saya mencoba untuk menghapus info_buyRequest
opsi dari semua produk di pengamat sales_quote_merge_before
, tanpa hasil.
Alasannya terletak di Mage_Sales_Model_Quote_Item_Abstract::getProduct()
mana opsi disalin lagi dari item kutipan itu sendiri:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
Larutan
Saya membuat penulisan ulang untuk Mage_Sales_Model_Quote_Item
dengan menimpa getProduct()
agar tidak menyertakan info_buyRequest
opsi pada saat ini:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
Ini menyebabkan masalah dengan produk bundel, alternatif di bawah ini atau tambalan resmi seperti yang dijelaskan oleh @ AnnaVölkl adalah solusi yang lebih baik
Alternatif
Anda juga bisa menghapus kesalahan && !$item->getProduct()->hasCustomOptions()
dalam compare()
metode jika Anda menulis ulang model barang. Saya tidak tahu masalah apa yang coba dipecahkannya, tetapi itu menciptakan lebih banyak ...
Perbarui 29 Jan 2016
Saya melaporkan ini ke Magento dan mendapat tanggapan bahwa mereka tidak dapat mereproduksi masalah, sehingga tambalan tidak akan membuatnya menjadi edisi komunitas (Submission APPSEC-1321).
Ini berarti, jika Anda memiliki masalah, Anda perlu menerapkan patch perusahaan SUPEE-6190 setelah setiap pembaruan atau menggunakan penulisan ulang kelas sebagai gantinya.