Il s'est avéré qu'il s'agit d'un bogue Mage_Sales_Model_Quote_Item::compare()
introduit dans Magento CE 1.9.2 / EE 1.14.2. La méthode est utilisée pour comparer les articles pour décider s'ils sont le même produit et peuvent être fusionnés (lors de la connexion et lors de l'ajout de produits au panier).
Lors de la comparaison de toutes les options personnalisées, il doit ignorer les options qui ne sont pas représentatives ( _notRepresentOptions
), à savoir l' option info_buyRequest .
Dans les versions précédentes de Magento, cela ressemblait à ceci:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)) {
continue;
}
et a fonctionné correctement. Maintenant, cela ressemble à ceci:
foreach ($this->getOptions() as $option) {
if (in_array($option->getCode(), $this->_notRepresentOptions)
&& !$item->getProduct()->hasCustomOptions()
) {
continue;
}
et la vérification supplémentaire des hasCustomOptions()
causes du bogue décrit. Pourquoi? Il semble que le chèque ait été ajouté pour toujours séparer les produits avec des options personnalisées. Je ne pense pas que cela ait du sens, du moins pas dans la manière dont il est mis en œuvre, mais il y a une raison à cela que je ne connais pas.
Cependant, $item->getProduct()->hasCustomOptions()
renvoie toujours vrai pour les articles de devis!
Voici la méthode:
public function hasCustomOptions()
{
if (count($this->_customOptions)) {
return true;
} else {
return false;
}
}
Mais $this->_customOptions
contient également l' info_buyRequest
option de l'élément de devis.
Pour une solution discrète, j'ai essayé de supprimer le info_buyRequest
option de tous les produits dans un observateur sales_quote_merge_before
, sans succès.
La raison en est Mage_Sales_Model_Quote_Item_Abstract::getProduct()
endroit où l'option est à nouveau copiée à partir de l'élément de devis lui-même:
public function getProduct()
{
$product = $this->_getData('product');
[...]
if (is_array($this->_optionsByCode)) {
$product->setCustomOptions($this->_optionsByCode);
}
return $product;
}
Solution
J'ai créé une réécriture pour Mage_Sales_Model_Quote_Item
avec un remplacement pour getProduct()
ne pas inclure l' info_buyRequest
option à ce stade:
public function getProduct()
{
$product = parent::getProduct();
$options = $product->getCustomOptions();
if (isset($options['info_buyRequest'])) {
unset($options['info_buyRequest']);
$product->setCustomOptions($options);
}
return $product;
}
Cela a causé des problèmes avec les produits groupés, l'alternative ci-dessous ou le patch officiel décrit par @ AnnaVölkl est une meilleure solution
Alternative
Vous pouvez également supprimer l'infraction && !$item->getProduct()->hasCustomOptions()
dans lecompare()
méthode si vous réécrivez de toute façon le modèle d'élément. Je ne sais pas quel problème il a essayé de résoudre, mais il en a créé plus ...
Mise à jour du 29 janvier 2016
J'ai signalé cela à Magento et j'ai obtenu la réponse qu'ils ne pouvaient pas reproduire le problème, donc le correctif ne sera pas intégré dans l'édition communautaire (Soumission APPSEC-1321).
Cela signifie que si vous rencontrez le problème, vous devez appliquer le correctif d'entreprise SUPEE-6190 après chaque mise à jour ou utiliser une réécriture de classe à la place.