Estoy trabajando en la cuadrícula del producto, pero su paginación o recuento de productos no funciona (ya que muestra un recuento incorrecto). como mi función de bloque _preparecollection es la siguiente: he agregado el código de filtro de categoría en la colección, así que tengo que usar una cláusula de grupo para evitar que exista un error para la misma identificación.
protected function _prepareCollection()
{
$store = $this->_getStore();
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('sku')
->addAttributeToSelect('name')
->addAttributeToSelect('attribute_set_id')
->addAttributeToSelect('type_id')
->joinField('category_id',
'catalog/category_product',
'category_id',
'product_id=entity_id',
null,
'left');
$collection->addAttributeToFilter('category_id', array('in' => array(4,10)))
->distinct(true);
$collection->getSelect()->group('e.entity_id');
if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
$collection->joinField('qty',
'cataloginventory/stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left');
}
$collection->joinField('position',
'catalog/category_product',
'position',
'product_id=entity_id',
null,
'left');
$collection->joinField('websites',
'catalog/product_website',
'website_id',
'product_id=entity_id',
null,
'left');
if ($store->getId()) {
//$collection->setStoreId($store->getId());
$adminStore = Mage_Core_Model_App::ADMIN_STORE_ID;
$collection->addStoreFilter($store);
$collection->joinAttribute(
'name',
'catalog_product/name',
'entity_id',
null,
'inner',
$adminStore
);
$collection->joinAttribute(
'custom_name',
'catalog_product/name',
'entity_id',
null,
'inner',
$store->getId()
);
$collection->joinAttribute(
'status',
'catalog_product/status',
'entity_id',
null,
'inner',
$store->getId()
);
$collection->joinAttribute(
'visibility',
'catalog_product/visibility',
'entity_id',
null,
'inner',
$store->getId()
);
$collection->joinAttribute(
'price',
'catalog_product/price',
'entity_id',
null,
'left',
$store->getId()
);
}
else {
$collection->addAttributeToSelect('price');
$collection->joinAttribute('status', 'catalog_product/status', 'entity_id', null, 'inner');
$collection->joinAttribute('visibility', 'catalog_product/visibility', 'entity_id', null, 'inner');
}
$this->setCollection($collection);
parent::_prepareCollection();
$this->getCollection()->addWebsiteNamesToResult();
return $this;
}
Tenía google y obtuve respuesta y la agregué a lib/varian/data/collection/db.php
public function getSelectCountSql()
{
$this->_renderFilters();
$countSelect = clone $this->getSelect();
$countSelect->reset(Zend_Db_Select::ORDER);
$countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
$countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
$countSelect->reset(Zend_Db_Select::COLUMNS);
if(count($this->getSelect()->getPart(Zend_Db_Select::GROUP)) > 0) {
$countSelect->reset(Zend_Db_Select::GROUP);
$countSelect->distinct(true);
$group = $this->getSelect()->getPart(Zend_Db_Select::GROUP);
$countSelect->columns("COUNT(DISTINCT ".implode(", ", $group).")");
} else {
$countSelect->columns('COUNT(*)');
}
return $countSelect;
}
Pero no hay suerte, por favor ayuda a resolver esto
magento-1.9
collection
collection-filtering
grid
Zaheerabbas
fuente
fuente
Mage_Adminhtml_Block_Widget_Grid
?Mage_Adminhtml_Block_Widget_Grid
Respuestas:
Colecciones y carga perezosa en Magento
La razón por la que la paginación no funciona es por cómo se cuentan las colecciones y cómo funciona la carga diferida con las colecciones.
Las colecciones en Magento implementan la clase
Countable
. Debido a la carga lenta de colecciones en Magento, cada vez quecount()
se llama al método , los datos deben cargarse. Como solución alternativa a esto, las colecciones implementan un método llamadogetSize()
. Clonará su declaración SQL, la envolverá en aCOUNT()
y devolverá el resultado. Esto permitió que una colección obtuviera un recuento total sin cargar todos los datos. Esto permite agregar cosas como filtros en el último minuto.Así es
Varien_Data_Collection_Db::getSize()
como segetSelectCountSql()
ve su socio :Básicamente, elimina límites, columnas, pedidos, etc. y deja los filtros atrás. Luego agrega un MySQL
COUNT()
a las columnas.El problema
Normalmente, en una tabla, esto devolvería una fila con el recuento total. Esta es la razón por la cual se
getSize()
hace unafetchOne()
contra la consulta. Sin embargo, al hacer cosas como uniones de tabla, bys de grupo y similares, no devolverá una fila, devolverá múltiples. Es por esto que necesita alterar elgetSize()
método en su colección.La solución
Así es como debería verse su método ahora:
En lugar de a
fetchOne()
, ejecutamos una funciónfetchAll()
envuelta encount()
PHP. Ahora sus totales volverán apropiadamente.fuente
Gran solución Quizás alguien tenga el mismo problema que nosotros, así que publicaré otra posible solución. En nuestro caso, teníamos una colección, que a veces incluía un grupo por declaración y otras no, según la cuadrícula donde se cargó la colección. Usando la solución anterior, encontramos dos problemas:
Después de depurar un tiempo descubrimos que en el caso 1 la parte
devuelve una matriz que tiene una entrada con valor 0. Es por eso que la función de conteo devuelve 1 aunque no se encontraron entradas.
En el caso 2, la misma parte devuelve una matriz con una entrada, cuyo valor es el tamaño real de la colección. La función de conteo nuevamente devuelve 1 y no el valor.
Al buscar una alternativa, descubrimos que la colección de productos utiliza una reescritura de la función getSelectCountSql (). Adaptamos esto y lo cambiamos un poco, lo que terminó en esta solución:
Resuelve los dos problemas que ya mencioné y, por lo que puedo ver, también funciona para los otros casos.
fuente