Я обнаружил странную ошибку в Magento EE 1.14.2 (также влияет на CE 1.9.2) с корзиной.
Действия по воспроизведению:
- Войти как клиент A
- Добавить продукт X в корзину
- Переключиться на другой браузер
- Добавить продукт X в корзину
- Войти как клиент A
Ожидаемая корзина:
- 2 х Продукт X
Фактическая корзина:
- 1 х продукт х
- 1 х продукт х
Т.е. продукты не объединены.
Вместо того, чтобы переключать браузер, вы также можете очистить cookie сессии или выбрать другой кол-во для продукта.
Худшим побочным эффектом этого является то, что максимальное количество заказа применяется для каждой позиции. В моем случае на товар была скидка 100%, но заказать его можно было только один раз. С этим маленьким трюком вы можете заказать его в любом количестве бесплатно.
Почему это происходит и как я могу предотвратить это?
источник
unset()
вызовам, но это по-прежнему небезопасно, поскольку любой произвольный параметр POST также добавляется в опцию buyRequest. Я собираюсь полностью игнорировать эту опцию.Оказалось, что это ошибка в
Mage_Sales_Model_Quote_Item::compare()
том, что было введено в Magento CE 1.9.2 / EE 1.14.2. Этот метод используется для сравнения товаров, чтобы определить, являются ли они одним и тем же товаром и могут ли быть объединены (при входе в систему и при добавлении товаров в корзину).При сравнении всех пользовательских параметров следует пропустить параметры, которые не являются represanative (
_notRepresentOptions
), а именно параметр info_buyRequest .В предыдущих версиях Magento это выглядело так:
и работал правильно. Теперь это выглядит так:
и дополнительная проверка для
hasCustomOptions()
причин описанной ошибки. Почему? Похоже, что проверка была добавлена, чтобы всегда держать продукты с настраиваемыми параметрами отдельно. Я не думаю, что это имеет смысл, по крайней мере, не в том, как это реализовано, но будет какая-то причина, о которой я не знаю.Тем не менее,
$item->getProduct()->hasCustomOptions()
всегда возвращает истину для цитат!Это метод:
Но
$this->_customOptions
также содержитinfo_buyRequest
опцию из цитаты.Для ненавязчивого решения я попытался удалить эту
info_buyRequest
опцию из всех продуктов в наблюдателеsales_quote_merge_before
, но безуспешно.Причина заключается в том,
Mage_Sales_Model_Quote_Item_Abstract::getProduct()
где опция снова копируется из самого элемента цитаты:Решение
Я создал перезапись для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 после каждого обновления или использовать вместо него переписывание классов.
источник
However, $item->getProduct()->hasCustomOptions() always returns true for quote items!
Он проверяет данные продукта для пользовательских опций, а не цитаты :)Как я вижу выше, ответ уже доступен в последней версии Magento, но проблема все еще не решена. Это не сработало, потому что мы сделали много настроек. Мысль о том, чтобы поделиться решением.
Для нас это было очень просто, так как мы используем только простые продукты. Итак, мы расширили функцию сравнения слиянием цитат до этой:
NS_Module_Model_Sales_Quote_Item extends Mage_Sales_Model_Quote_Item {
}
и добавил
но. для тех, кто использует настраиваемые продукты, то это может быть не полезно для вас. В этом случае вы можете напечатать оба массива: $ itemOptionValue и $ optionValue и увидеть разницу. сбросьте все дополнительные ключи, которые не являются общими в обоих массивах. Это должно решить проблему.
источник
Вы можете просто добавить опцию к товару в событии sales_quote_add_item:
Ссылка: Отключить слияние позиций корзины?
источник