Оказалось, что это ошибка в Mage_Sales_Model_Quote_Item::compare()
том, что было введено в Magento CE 1.9.2 / EE 1.14.2. Этот метод используется для сравнения товаров, чтобы определить, являются ли они одним и тем же товаром и могут ли быть объединены (при входе в систему и при добавлении товаров в корзину).
При сравнении всех пользовательских параметров следует пропустить параметры, которые не являются represanative ( _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 и получил ответ, что они не могут воспроизвести проблему, поэтому исправление не войдет в выпуск сообщества (представление APPSEC-1321).
Это означает, что если у вас есть проблема, вам нужно применять исправление Enterprise SUPEE-6190 после каждого обновления или использовать вместо него переписывание классов.