Si è scoperto che si Mage_Sales_Model_Quote_Item::compare()
trattava di un bug introdotto in Magento CE 1.9.2 / EE 1.14.2. Il metodo viene utilizzato per confrontare gli articoli per decidere se sono lo stesso prodotto e possono essere uniti (durante il login e quando si aggiungono prodotti al carrello).
Quando si confrontano tutte le opzioni personalizzate, è necessario saltare le opzioni non rappresentative ( _notRepresentOptions
), ovvero l' opzione info_buyRequest .
Nelle precedenti versioni di Magento, era simile al seguente:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
e ha funzionato correttamente. Ora sembra così:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
e il controllo aggiuntivo per hasCustomOptions()
causa l'errore descritto. Perché? Sembra che il controllo sia stato aggiunto per mantenere sempre separati i prodotti con opzioni personalizzate. Non penso che abbia senso, almeno non nel modo in cui è implementato, ma ci saranno alcuni motivi per cui non sono a conoscenza.
Tuttavia, $item->getProduct()->hasCustomOptions()
restituisce sempre true per gli articoli di preventivo!
Questo è il metodo:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
Ma $this->_customOptions
contiene anche l' info_buyRequest
opzione dalla voce di preventivo.
Per una soluzione discreta, ho provato a rimuovere l' info_buyRequest
opzione da tutti i prodotti in un osservatore attivo sales_quote_merge_before
, senza successo.
Il motivo sta nel fatto che Mage_Sales_Model_Quote_Item_Abstract::getProduct()
l'opzione viene copiata nuovamente dall'elemento preventivo stesso:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
Soluzione
Ho creato una riscrittura per Mage_Sales_Model_Quote_Item
con una sostituzione per getProduct()
non includere l' info_buyRequest
opzione a questo punto:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
Ciò ha causato problemi con i prodotti in bundle, l'alternativa di seguito o la patch ufficiale descritta da @ AnnaVölkl è una soluzione migliore
Alternativa
È inoltre possibile rimuovere l'offesa && !$item->getProduct()->hasCustomOptions()
nel compare()
metodo se si riscrive comunque il modello di articoli. Non so quale problema ha cercato di risolvere, ma ha creato di più ...
Aggiornamento del 29 gennaio 2016
Ho segnalato questo a Magento e ho avuto la risposta che non potevano riprodurre il problema, quindi la patch non lo avrebbe trasformato nell'edizione della comunità (Invio APPSEC-1321).
Ciò significa che, se si verifica il problema, è necessario applicare la patch aziendale SUPEE-6190 dopo ogni aggiornamento o utilizzare invece una riscrittura di classe.