TL; DR : el requisito es que se muestre un nivel de inventario en la página de listado de productos de categoría con tan pocas consultas / memoria adicionales con un rendimiento en mente que se adhiere al marco de Magento.
Después de leer el artículo de Vinai Kopp sobre precarga para la escalabilidad .
¿Cuál es la mejor manera de incluir los niveles de inventario en las páginas de listado de productos de categoría ( list.phtml ) con tan pocas consultas / cargas adicionales por motivos de rendimiento?
Soy consciente de algunos enfoques:
afterLoad () parece funcionar bien con lamedia_gallery
inclusión sin consultas adicionales, sin embargo, no he tenido éxito al implementar el mismo enfoque con el inventario.
$attributes = $_product->getTypeInstance(true)->getSetAttributes($_product);
$media_gallery = $attributes['media_gallery'];
$backend = $media_gallery->getBackend();
$backend->afterLoad($_product);
SQL directo para recopilar los datos necesarios en paralelo a la recopilación con una product_id
clave, por ejemplo. Pero buscando más medios a través del marco.
Actualmente simplemente estoy cargando el stock_item
objeto a través de:
$_product->load('stock_item')->getTotalQty();
Lo que funciona, pero noto la adición de más consultas para obtener el inventario total de todos los productos de la colección.
...
__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)
...
Curiosamente, esto funciona. La magia ocurre en Mage_Eav_Model_Entity_Abstract-> load ($ object, $ entityId, $ atributos). Si $ atributos está vacío, llamará a loadAllAttribute ($ objeto). Entonces $ product-> load ('blah') cargará todos los atributos faltantes, incluyendo 'media_gallery' - William Tran 19 de noviembre de 14 a las 4:45
Agregue los valores necesarios a la colección ya cargada.
El enfoque simple obvio de agregar los datos necesarios a la colección de producción de nivel superior en la capa / filtro, parece ser el mejor enfoque.
Me di cuenta de un observador addInventoryDataToCollection () en Mage_CatalogInventory_Model_Observer que parece que lo lograría, pero agregar el método a un observador de módulos personalizados no parece ser compatible.
<events>
<catalog_product_collection_load_after>
<observers>
<inventory>
<class>cataloginventory/observer</class>
<method>addInventoryDataToCollection</method>
</inventory>
</observers>
</catalog_product_collection_load_after>
</events>
Lo que resulta en:
Advertencia: argumento no válido proporcionado para foreach () en /app/code/core/Mage/CatalogInventory/Model/Resource/Stock/Item/Collection.php en la línea 71
fuente
Respuestas:
El verdadero problema aquí no es la precarga, es la precisión. Es relativamente fácil obtener la cantidad de existencias para una colección de productos:
Ahora con dos consultas, tiene toda la información que necesita. Simplemente son difíciles de relacionar entre sí, lo que se puede solucionar mediante el uso de una matriz asociativa
'product_id' => 'stock'
y escribiendo un captador. Además, addProductsFilter se puede optimizar:Esto le ahorra la verificación de tipo y la clonación de matrices.
El problema ahora es Bloquear caché HTML. Esta página de categoría debe purgarse cuando se actualiza cualquier stock de un producto contenido en él. Hasta donde sé, esto no es estándar, ya que solo un cambio en el estado de las existencias elimina una página de categoría que contiene un producto (o más exactamente, un cambio de visibilidad). Por lo tanto, deberá observar al menos
cataloginventory_stock_item_before_save
y tal vez algunos otros y purgar el caché html de bloque (y el caché FPC) para esa página de categoría.fuente
Veo que ya ha aceptado y, sin duda, ha implementado algo por ahora, sin embargo, me gustaría señalar lo cerca que estaba,
addInventoryDataToCollection()
pero parece que ha citado incorrectamente el archivo de configuración o estamos usando versiones muy diferentes de magento. Mi copia deCatalogInventory/etc/config.xml
tiene un método diferente paracatalog_product_collection_load_after
addInventoryDataToCollection()
se llama en<sales_quote_item_collection_products_after_load>
La fuente
addStockStatusToCollection()
es:Puede establecer el indicador
require_stock_items
en la colección antes de que se cargue, probablemente no sea tan fácil para el bloque detrás de la lista de categorías, o puede llamarMage::getModel('cataloginventory/stock')->addItemsToProducts($productCollection)
manualmente a la colección, después de que ya esté cargada.addItemsToProducts()
obtiene todos los artículos de stock para usted y los adjunta a su colección de productosfuente
¿Estás usando Varnish o FPC en absoluto, o planeas hacerlo en el futuro?
Descubrimos que con la cantidad de perforaciones / solicitudes de ESI requeridas en las listas de productos, casi no valía la pena tener el almacenamiento en caché en su lugar, por lo que optamos por un enfoque diferente.
Implementamos una solución en un sitio web que utiliza una solicitud AJAX a un controlador personalizado para recuperar los datos de stock de los productos y el JavaScript maneja las actualizaciones DOM. La solicitud adicional de los datos de inventario tarda ~ 100 ms, lo que no afecta en absoluto el tiempo de carga de la página (visible) general. Si a esto le sumamos que con el FPC preparado reduciendo la solicitud de la página a menos de 100 ms, tiene un sitio rápido con una sobrecarga de bajo rendimiento para mostrar datos de stock en las listas de productos.
Todo lo que necesita hacer con una plantilla inteligente es agregar el productId a cada contenedor de productos html para que su javascript sepa qué datos de stock aplicar a cada producto.
Si observa técnicas de almacenamiento en caché adicionales para los datos de existencias reales, podría caer muy por debajo de 100 ms al no tener que iniciar Mage / golpear la base de datos en cada solicitud.
Lo sentimos si esto no está en la línea de lo que está buscando, pero descubrimos que es el mejor enfoque para la escalabilidad y el rendimiento según nuestros requisitos.
fuente