Okazało się, że jest to błąd, Mage_Sales_Model_Quote_Item::compare()
który został wprowadzony w Magento CE 1.9.2 / EE 1.14.2. Ta metoda służy do porównywania produktów w celu ustalenia, czy są one tym samym produktem i mogą zostać połączone (podczas logowania i dodawania produktów do koszyka).
Porównując wszystkie opcje niestandardowe, należy pominąć opcje, które nie są represantatywne ( _notRepresentOptions
), a mianowicie opcję info_buyRequest .
W poprzednich wersjach Magento wyglądało to tak:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
i działał poprawnie. Teraz wygląda to tak:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
a dodatkowe sprawdzenie hasCustomOptions()
powoduje opisany błąd. Dlaczego? Wygląda na to, że czek został dodany, aby zawsze przechowywać osobne produkty z niestandardowymi opcjami. Nie sądzę, żeby miało to sens, przynajmniej nie w sposobie jego implementacji, ale będzie jakiś powód, którego nie jestem świadomy.
Jednak $item->getProduct()->hasCustomOptions()
zawsze zwraca true dla pozycji cytując!
To jest metoda:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
Ale $this->_customOptions
zawiera również info_buyRequest
opcję z pozycji cytatu.
Aby uzyskać dyskretne rozwiązanie, próbowałem usunąć tę info_buyRequest
opcję ze wszystkich produktów w obserwatorze sales_quote_merge_before
bezskutecznie.
Powodem jest Mage_Sales_Model_Quote_Item_Abstract::getProduct()
to, że opcja jest kopiowana ponownie z samego cytatu:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
Rozwiązanie
Utworzyłem przepisanie Mage_Sales_Model_Quote_Item
z przesłonięciem, getProduct()
aby nie uwzględniać info_buyRequest
opcji w tym momencie:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
To spowodowało problemy z pakietami produktów, alternatywą poniżej lub oficjalną łatką opisaną przez @ AnnaVölkl jest lepszym rozwiązaniem
Alternatywny
Możesz również usunąć przestępstwo && !$item->getProduct()->hasCustomOptions()
w compare()
metodzie, jeśli i tak przepisujesz model przedmiotu. Nie wiem, jaki problem próbował rozwiązać, ale stworzył więcej ...
Aktualizacja 29 stycznia 2016 r
Zgłosiłem to Magento i otrzymałem odpowiedź, że nie mogą odtworzyć problemu, więc łatka nie pojawi się w wydaniu społecznościowym (Submission APPSEC-1321).
Oznacza to, że jeśli masz problem, musisz zastosować poprawkę korporacyjną SUPEE-6190 po każdej aktualizacji lub zamiast tego użyć przepisania klasy.