TL; DR , L'exigence est d'avoir un niveau de stock d'inventaire affiché sur la page de liste des produits de la catégorie avec aussi peu de requêtes / mémoire supplémentaires avec des performances à l'esprit qui adhèrent au cadre de Magento.
Après avoir lu l'article de Vinai Kopp sur le préchargement pour l'évolutivité .
Quelle est la meilleure façon d'inclure les niveaux de stock dans les pages de liste des produits de la catégorie ( list.phtml ) avec aussi peu de requêtes / chargements supplémentaires pour des raisons de performances?
Je connais quelques approches:
afterLoad () semble bien fonctionner avec l'media_gallery
inclusion sans requêtes supplémentaires, mais je n'ai pas réussi à implémenter la même approche avec l'inventaire.
$attributes = $_product->getTypeInstance(true)->getSetAttributes($_product);
$media_gallery = $attributes['media_gallery'];
$backend = $media_gallery->getBackend();
$backend->afterLoad($_product);
Demandez à SQL de collecter les données requises en parallèle à la collecte avec une product_id
clé par exemple. Mais à la recherche de plus de moyens dans le cadre.
Actuellement, je charge simplement l' stock_item
objet via:
$_product->load('stock_item')->getTotalQty();
Ce qui fonctionne, mais je remarque l'ajout de plus de requêtes pour obtenir le total des stocks de tous les produits de la collection.
...
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
__EAV_LOAD_MODEL__ (Mage_Catalog_Model_Product, id: stock_item, attributes: NULL)
...
étrangement, cela fonctionne. La magie opère dans Mage_Eav_Model_Entity_Abstract-> load ($ object, $ entityId, $ attributes). Si $ attributes est vide, il appellera loadAllAttribute ($ object). Donc $ product-> load ('blah') chargera tous les attributs manquants, y compris 'media_gallery' - William Tran 19 novembre 14 à 4:45
Ajoutez les valeurs nécessaires à la collection déjà chargée.
L'approche simple évidente consistant à ajouter les données nécessaires à la collection de production de niveau supérieur dans la couche / le filtre semble être la meilleure approche.
J'ai remarqué un observateur addInventoryDataToCollection () dans Mage_CatalogInventory_Model_Observer qui semble pouvoir y arriver, mais l'ajout de la méthode à un observateur de modules personnalisés ne semble pas compatible.
<events>
<catalog_product_collection_load_after>
<observers>
<inventory>
<class>cataloginventory/observer</class>
<method>addInventoryDataToCollection</method>
</inventory>
</observers>
</catalog_product_collection_load_after>
</events>
Ce qui se traduit par:
Avertissement: argument non valide fourni pour foreach () dans /app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item/Collection.php sur la ligne 71
Réponses:
Le vrai problème ici n'est pas le préchargement, c'est la précision. Il est relativement facile d'obtenir le montant du stock pour une collection de produits:
Maintenant, avec deux requêtes, vous avez toutes les informations dont vous avez besoin. Ils sont juste difficiles à relier les uns aux autres, ce qui peut être corrigé en utilisant un tableau associatif
'product_id' => 'stock'
et en écrivant un getter. De plus, addProductsFilter peut être optimisé:Cela vous évite la vérification de type et le clonage de tableau.
Le problème est maintenant de bloquer le cache HTML. Cette page de catégorie doit être purgée lorsqu'un stock est mis à jour sur un produit qu'il contient. Pour autant que je sache, ce n'est pas standard, car seul un changement d'état des stocks purge une page de catégorie contenant un produit (ou plus précisément, un changement de visibilité). Vous devrez donc observer au moins
cataloginventory_stock_item_before_save
et peut-être quelques autres et purger le cache html du bloc (et le cache FPC) pour cette page de catégorie.la source
Je vois que vous avez déjà accepté et sans aucun doute implémenté quelque chose maintenant, mais je voudrais souligner à quel point vous étiez proche,
addInventoryDataToCollection()
mais il semble que vous ayez mal cité le fichier de configuration ou que nous utilisons des versions très différentes de magento. Ma copieCatalogInventory/etc/config.xml
a une méthode différente appeléecatalog_product_collection_load_after
addInventoryDataToCollection()
est appelé<sales_quote_item_collection_products_after_load>
La source de
addStockStatusToCollection()
est:Vous pouvez soit définir l'indicateur
require_stock_items
sur la collection avant qu'elle ne soit chargée, probablement pas aussi simple pour le bloc derrière la liste des catégories, soit appelerMage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection)
manuellement sur la collection, une fois qu'elle est déjà chargée.addItemsToProducts()
obtient tous les StockItems pour vous et les attache à votre ProductCollectionla source
Utilisez-vous du vernis ou du FPC ou prévoyez-vous de le faire à l'avenir?
Nous avons constaté qu'avec le nombre de perforations / demandes ESI requises sur les listes de produits, la mise en cache ne valait presque pas la peine, alors nous avons opté pour une approche différente.
Nous avons implémenté une solution sur un site Web qui utilise une demande AJAX à un contrôleur personnalisé pour récupérer les données de stock des produits et le javascript gère les mises à jour DOM. La demande supplémentaire pour les données de stock prend environ 100 ms, ce qui n'a aucun impact sur le temps de chargement de la page (visible). Ajoutez à cela qu'avec le FPC amorcé qui réduit la demande de page à moins de 100 ms, vous avez un site rapide avec des frais généraux de faible performance pour afficher les données de stock sur les listes de produits.
Tout ce que vous devez faire en termes de modèle est d'ajouter le productId à chaque emballage de produits html afin que votre javascript sache quelles données de stock appliquer à chaque produit.
Si vous regardez des techniques de mise en cache supplémentaires pour les données de stock réelles, vous pouvez descendre bien en dessous de 100 ms en n'ayant pas à lancer Mage / frapper la base de données à chaque demande.
Désolé si cela ne correspond pas à ce que vous recherchez, mais nous avons trouvé que c'était la meilleure approche pour l'évolutivité et les performances par rapport à nos exigences.
la source