Je travaille sur la grille des produits mais sa pagination ou le nombre de produits ne fonctionne pas (car ils affichent un nombre incorrect). comme ma fonction de _preparecollection de bloc est comme ci-dessous. j'ai ajouté le code de filtre de catégorie dans la collection ainsi je dois employer la clause de groupe pour empêcher l'erreur pour le même id existent déjà.
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;
}
J'avais google et obtenu une réponse et l'ajouter à 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;
}
Mais pas de chance, aidez à résoudre ce problème
magento-1.9
collection
collection-filtering
grid
Zaheerabbas
la source
la source
Mage_Adminhtml_Block_Widget_Grid
?Mage_Adminhtml_Block_Widget_Grid
Réponses:
Collections et chargement paresseux dans Magento
La pagination ne fonctionne pas en raison de la façon dont les collections sont comptées et du fonctionnement du chargement paresseux avec les collections.
Les collections dans Magento implémentent la classe
Countable
. En raison du chargement paresseux des collections dans Magento, chaque fois que la méthodecount()
est appelée, les données doivent être chargées. Pour contourner ce problème, les collections implémentent une méthode appeléegetSize()
. Il clonera votre instruction SQL, l'enveloppera dans unCOUNT()
et retournera le résultat. Cela a permis à une collection d'obtenir un nombre total sans charger toutes les données. Cela permet d'ajouter des éléments tels que des filtres à la dernière minute.Voici à quoi ressemble son
Varien_Data_Collection_Db::getSize()
partenairegetSelectCountSql()
:Fondamentalement, il supprime les limites, les colonnes, les commandes, etc. et laisse les filtres derrière. Ensuite, il ajoute un MySQL
COUNT()
aux colonnes.Le problème
Normalement, sur une table, cela retournerait une ligne avec le nombre total. C'est pourquoi
getSize()
fait unfetchOne()
contre la requête. Cependant, lorsque vous effectuez des opérations telles que des jointures de table, des bys de groupe, etc., vous ne retournerez pas une ligne, vous en retournerez plusieurs. C'est à cause de cela que vous devez modifier lagetSize()
méthode dans votre collection.La solution
Voici à quoi devrait ressembler votre méthode maintenant:
Au lieu d'un
fetchOne()
, nous avons exécuté unfetchAll()
enveloppé dans unecount()
fonction PHP. Maintenant, vos totaux reviendront de manière appropriée.la source
Excellente solution. Peut-être que quelqu'un a le même problème que nous, alors je publierai une autre solution possible. Dans notre cas, nous avions une collection, qui comprenait parfois une instruction group by et parfois non, selon la grille où la collection était chargée. En utilisant la solution ci-dessus, nous avons trouvé deux problèmes:
Après avoir débogué un moment, nous avons découvert que, dans le cas 1, la partie
renvoie un tableau qui a une entrée avec la valeur 0. C'est pourquoi la fonction count renvoie 1 bien qu'aucune entrée n'ait été trouvée.
Dans le cas 2, la même partie renvoie un tableau avec une entrée, dont la valeur est la taille réelle de la collection. La fonction de comptage renvoie à nouveau 1 et non la valeur.
En recherchant une alternative, nous avons découvert que la collection de produits utilise une réécriture de la fonction getSelectCountSql (). Nous l'avons adapté et changé un peu, ce qui a abouti à cette solution:
Cela résout les deux problèmes que j'ai déjà mentionnés et, pour autant que je sache, cela fonctionne également pour les autres cas.
la source