Виявилося, що це помилка 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()
завжди повертає істину для предметів цитат!
Це метод:
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()
методі, якщо ви все одно перепишете модель товару. Я не знаю, яку проблему вона намагалася вирішити, але це створило більше ...
Оновити 29 січня 2016 року
Я повідомив про це Magento і отримав відповідь, що вони не можуть відтворити проблему, тому патч не ввійде у видання для громади (Submission APPSEC-1321).
Це означає, що якщо у вас є проблеми, вам потрібно застосувати корпоративний патч SUPEE-6190 після кожного оновлення або використовувати замість цього перезапис класу.