TL; DR , Die Anforderung besteht darin, dass der Lagerbestand auf der Seite mit den Produktlisten der Kategorie mit möglichst wenig zusätzlichen Abfragen / Speicher angezeigt wird, um die Leistung zu gewährleisten, die dem Magento-Framework entspricht.
Nach dem Lesen von Vinai Kopps Artikel über das Vorladen für Skalierbarkeit .
Was ist der beste Weg, um die Lagerbestände auf den Seiten mit den Produktlisten der Kategorie ( list.phtml ) mit möglichst wenigen zusätzlichen Abfragen / Ladevorgängen aus Gründen der Leistung einzuschließen?
Mir sind einige Ansätze bekannt:
afterLoad () scheint gut mitmedia_gallery
Inklusion ohne zusätzliche Abfragenzu funktionieren, es ist mir jedoch nicht gelungen, denselben Ansatz mit Inventory zu implementieren.
$attributes = $_product->getTypeInstance(true)->getSetAttributes($_product);
$media_gallery = $attributes['media_gallery'];
$backend = $media_gallery->getBackend();
$backend->afterLoad($_product);
Direktes SQL zum Sammeln der erforderlichen Daten parallel zur Sammlung, beispielsweise mit einem product_id
Schlüssel. Suche aber eher nach einem Mittel durch das Framework.
Momentan lade ich das stock_item
Objekt einfach über:
$_product->load('stock_item')->getTotalQty();
Was funktioniert, aber ich stelle fest, dass weitere Abfragen hinzugefügt wurden, um den Lagerbestand aller Produkte in der Sammlung zu ermitteln.
...
__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)
...
seltsamerweise funktioniert dies. Die Magie geschieht in Mage_Eav_Model_Entity_Abstract-> load ($ object, $ entityId, $ attributes). Wenn $ attributes leer ist, wird loadAllAttribute ($ object) aufgerufen. $ Product-> load ('blah') lädt also alle fehlenden Attribute, einschließlich 'media_gallery' - William Tran 19. November 14 um 4:45
Fügen Sie der bereits geladenen Sammlung die erforderlichen Werte hinzu.
Der naheliegende einfache Ansatz, die erforderlichen Daten der Produktionssammlung der obersten Ebene im Layer / Filter hinzuzufügen, scheint der beste Ansatz zu sein.
Ich habe in Mage_CatalogInventory_Model_Observer einen Beobachter namens addInventoryDataToCollection () festgestellt , der sich so anhört, als würde er dies erreichen. Das Hinzufügen der Methode zu einem benutzerdefinierten Modulbeobachter scheint jedoch nicht kompatibel zu sein.
<events>
<catalog_product_collection_load_after>
<observers>
<inventory>
<class>cataloginventory/observer</class>
<method>addInventoryDataToCollection</method>
</inventory>
</observers>
</catalog_product_collection_load_after>
</events>
Was in ... endet:
Warnung: Ungültiges Argument für foreach () in /app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item/Collection.php in Zeile 71
quelle
Antworten:
Das eigentliche Problem ist hier nicht das Vorladen, sondern die Genauigkeit. Es ist relativ einfach, den Lagerbestand für eine Sammlung von Produkten zu ermitteln:
Jetzt haben Sie mit zwei Abfragen alle Informationen, die Sie benötigen. Sie sind nur schwer miteinander in Beziehung zu setzen, was durch die Verwendung eines assoziativen Arrays
'product_id' => 'stock'
und das Schreiben eines Getters behoben werden kann . Außerdem kann addProductsFilter optimiert werden:Dies erspart Ihnen die Typprüfung und das Klonen von Arrays.
Das Problem ist jetzt Block HTML Cache. Diese Kategorieseite muss gelöscht werden, wenn der Lagerbestand eines darin enthaltenen Produkts aktualisiert wird. Soweit ich weiß, ist dies kein Standard, da nur eine Änderung des Lagerstatus eine Kategorieseite löscht, die ein Produkt enthält (genauer gesagt eine Änderung der Sichtbarkeit). Sie müssen also mindestens
cataloginventory_stock_item_before_save
einige andere beobachten und den Block-HTML-Cache (und den FPC-Cache) für diese Kategorieseite leeren.quelle
Ich sehe, dass Sie bereits etwas akzeptiert und zweifellos bereits implementiert haben. Ich möchte jedoch darauf hinweisen, wie nah Sie dran waren,
addInventoryDataToCollection()
aber es sieht so aus, als hätten Sie die Konfigurationsdatei falsch zitiert, oder wir verwenden sehr unterschiedliche Versionen von Magento. Meine Kopie vonCatalogInventory/etc/config.xml
hat eine andere Methode verlangtcatalog_product_collection_load_after
addInventoryDataToCollection()
wird angerufen<sales_quote_item_collection_products_after_load>
Die Quelle für
addStockStatusToCollection()
ist:Sie können entweder das Flag
require_stock_items
für die Sammlung setzen, bevor sie geladen wird, was für den Block hinter der Kategorieliste wahrscheinlich nicht so einfach ist, oder Sie könnenMage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection)
die Sammlung manuell aufrufen , nachdem sie bereits geladen wurde.addItemsToProducts()
Ruft alle StockItems für Sie ab und hängt sie an Ihre ProductCollection anquelle
Verwenden Sie Varnish oder FPC überhaupt oder planen Sie es in Zukunft?
Wir haben festgestellt, dass es sich bei der Anzahl der erforderlichen Lochungen / ESI-Anforderungen in den Produktlisten kaum gelohnt hat, das Caching einzurichten, sodass wir uns für einen anderen Ansatz entschieden haben.
Wir haben eine Lösung auf einer Website implementiert, die eine AJAX-Anfrage an einen benutzerdefinierten Controller verwendet, um die Bestandsdaten für die Produkte abzurufen, und das Javascript übernimmt die DOM-Aktualisierungen. Die zusätzliche Anforderung der Bestandsdaten dauert ca. 100 ms, was sich überhaupt nicht auf die gesamte (sichtbare) Ladezeit der Seite auswirkt. Wenn Sie die Seitenanforderung mit vorbereiteter FPC auf unter 100 ms reduzieren, haben Sie eine schnelle Site mit geringem Leistungsaufwand für die Anzeige von Bestandsdaten in den Produktlisten.
Alles, was Sie tun müssen, um eine Vorlage zu erstellen, ist das Hinzufügen der productId zu jedem Produkt-Wrapper-HTML, damit Ihr Javascript weiß, welche Bestandsdaten für jedes Produkt gelten sollen.
Wenn Sie sich zusätzliche Zwischenspeichertechniken für die tatsächlichen Bestandsdaten ansehen, können Sie diese deutlich unter 100 ms senken, indem Sie nicht bei jeder Anforderung Mage / Hit in die Datenbank einleiten müssen.
Es tut uns leid, wenn dies nicht dem entspricht, was Sie suchen, aber wir haben festgestellt, dass dies der beste Ansatz für Skalierbarkeit und Leistung in Bezug auf unsere Anforderungen ist.
quelle