Remarque: Si vous avez modifié des produits par du code PHP, ré-indexez-les ensuite dans l'administrateur, économisez vos heures en essayant de comprendre pourquoi ils ne s'affichent pas comme moi ci-dessous ...
Je tourne en rond en essayant de comprendre comment is_salable
est défini pour un produit, et donc pourquoi mes produits s'affichent maintenant.
Il n'y a qu'un seul endroit dans le code que je peux trouver qui le définit:
$salable = $this->isAvailable();
mais je ne peux pas trouver comment ni où cela va isAvailable
venir , car quand je le suis, il semble que ça tourne en rond ...
/app/code/core/Mage/Catalog/Model/Product.php
public function isSalable()
{
Mage::dispatchEvent('catalog_product_is_salable_before', array(
'product' => $this
));
$salable = $this->isAvailable();
$object = new Varien_Object(array(
'product' => $this,
'is_salable' => $salable
));
Mage::dispatchEvent('catalog_product_is_salable_after', array(
'product' => $this,
'salable' => $object
));
return $object->getIsSalable();
}
suivant $ this-> isAvailable () à partir d'ici, il va quelques lignes:
**public function isAvailable()
{
return $this->getTypeInstance(true)->isSalable($this);
}**
cela appelle ensuite app / code / core / Mage / Catalog / Model / Product / Type / Configurable.php's isSalable
public function isSalable($product = null)
{
$salable = parent::isSalable($product);
if ($salable !== false) {
$salable = false;
if (!is_null($product)) {
$this->setStoreFilter($product->getStoreId(), $product);
}
foreach ($this->getUsedProducts(null, $product) as $child) {
if ($child->isSalable()) {
$salable = true;
break;
}
}
}
return $salable;
}
qui appelle le parent: isappel de /app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php:
public function isSalable($product = null)
{
$salable = $this->getProduct($product)->getStatus() == Mage_Catalog_Model_Product_Status::STATUS_ENABLED;
if ($salable && $this->getProduct($product)->hasData('is_salable')) {
$salable = $this->getProduct($product)->getData('is_salable');
}
elseif ($salable && $this->isComposite()) {
$salable = null;
}
return (boolean) (int) $salable;
}
qui fait juste un appel has / get data sur la valeur is_saleable?!? Ai-je suivi cela correctement? D'où vient cette valeur?
J'ai émis un grep récursif sur mon installation pour is_salable, cela devrait sûrement montrer toutes les lignes où il est défini mais je n'en vois pas tout de suite:
grep -r is_salable *
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php: $object = new Varien_Object(array('is_in_stock' => $product->getData('is_salable')));
app/code/core/Mage/XmlConnect/Block/Wishlist.php: $itemXmlObj->addChild('is_salable', (int)$item->getProduct()->isSalable());
app/code/core/Mage/XmlConnect/Block/Catalog/Product.php: $item->addChild('is_salable', (int)$product->isSalable());
app/code/core/Mage/XmlConnect/Block/Cart/Crosssell.php: $itemXmlObj->addChild('is_salable', 0);
app/code/core/Mage/XmlConnect/Block/Cart/Crosssell.php: $itemXmlObj->addChild('is_salable', (int)$product->isSalable());
app/code/core/Mage/Catalog/Model/Product.php: Mage::dispatchEvent('catalog_product_is_salable_before', array(
app/code/core/Mage/Catalog/Model/Product.php: 'is_salable' => $salable
app/code/core/Mage/Catalog/Model/Product.php: Mage::dispatchEvent('catalog_product_is_salable_after', array(
app/code/core/Mage/Catalog/Model/Product.php: if ($this->hasData('is_salable')) {
app/code/core/Mage/Catalog/Model/Product.php: return $this->getData('is_salable');
app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php: if ($salable && $this->getProduct($product)->hasData('is_salable')) {
app/code/core/Mage/Catalog/Model/Product/Type/Abstract.php: $salable = $this->getProduct($product)->getData('is_salable');
A TROUVÉ:
grep -r setIsSalable *
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php: $product->setIsSalable($stockStatus);
app/code/core/Mage/CatalogInventory/Model/Stock/Status.php: $product->setIsSalable($status);
C'était setIsSalable que je ne pensais pas / ne savais pas chercher plutôt que setIsSalable .
catalog_product_collection_load_after
. Mais ce n'est qu'un exemple. Il y a aussicataloginventory/observer::addInventoryData
que les appelsassignProduct
que les ensemblesis_salable
. Il pourrait y en avoir d'autres mais je ne cherchais pas tout.catalog_product_
et déboguer les méthodes appelées par les observateurs sur ces événements. et voyez si on appellesetIsSalable
ousetData('is_salable')
si est vendable renvoie faux, la réindexation peut également avoir un problème de réindexation des données
la source
Si, après réindexation et débogage, is_salable to no end et que votre produit configurable s'affiche toujours en rupture de stock, assurez-vous que tous les simples ont le statut défini sur Enabled, dans TOUTES les vues du magasin. J'ai juste perdu deux heures à me demander pourquoi un configurable était en rupture de stock, peu importe ce que je faisais, jusqu'à ce que je vérifie toutes les vues du magasin et découvre qu'un organisme a désactivé le statut.
la source