Estou trabalhando na grade do produto, mas sua paginação ou contagem de produtos não está funcionando (pois exibe contagem incorreta). Como minha função de bloco _preparecollection é a seguir, adicionei o código de filtro de categoria na coleção, portanto, tenho que usar a cláusula de grupo para evitar que já exista um erro para o mesmo ID.
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;
}
Eu tinha o google e obtive resposta e adicione-o 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;
}
Mas sem sorte, por favor, ajude a resolver isso
magento-1.9
collection
collection-filtering
grid
Zaheerabbas
fonte
fonte
Mage_Adminhtml_Block_Widget_Grid
?Mage_Adminhtml_Block_Widget_Grid
Respostas:
Coleções e carregamento lento no Magento
A razão pela qual a paginação não funciona é devido à maneira como as coleções são contadas e como o carregamento lento funciona com as coleções.
Coleções no Magento implementam a classe
Countable
. Devido ao carregamento lento de coleções no Magento, sempre que o métodocount()
é chamado, os dados precisam ser carregados. Como solução alternativa, as coleções implementam um método chamadogetSize()
. Ele irá clonar sua instrução SQL, envolvê-la emCOUNT()
e retornar o resultado. Isso permitiu que uma coleção obtivesse uma contagem total sem carregar todos os dados. Isso permite que itens como filtros sejam adicionados no último minuto.É assim que é
Varien_Data_Collection_Db::getSize()
e é o parceirogetSelectCountSql()
:Basicamente, elimina limites, colunas, pedidos, etc. e deixa os filtros para trás. Em seguida, ele adiciona um MySQL
COUNT()
às colunas.O problema
Normalmente, em uma tabela, isso retornaria uma linha com a contagem total. É por
getSize()
isso que fazfetchOne()
contra a consulta. No entanto, ao fazer coisas como junções de tabelas, agrupamentos de itens e similares, você não retornará uma linha, retornará várias. É por isso que você precisa alterar ogetSize()
método em sua coleção.A solução
É assim que seu método deve ser agora:
Em vez de a
fetchOne()
, executamos umfetchAll()
empacotado em umacount()
função PHP. Agora seus totais retornarão adequadamente.fonte
Ótima solução. Talvez alguém tenha o mesmo problema que o nosso, por isso postarei outra solução possível. No nosso caso, tínhamos uma coleção, que algumas vezes incluía um grupo por declaração e outras vezes, dependendo da grade em que a coleção foi carregada. Usando a solução acima, encontramos dois problemas:
Depois de depurar um pouco, descobrimos que, no caso 1, a parte
retorna uma matriz que possui uma entrada com o valor 0. É por isso que a função count retorna 1, embora nenhuma entrada tenha sido encontrada.
No caso 2, a mesma parte retorna uma matriz com uma entrada, cujo valor é o tamanho real da coleção. A função count novamente retorna 1 e não o valor.
Buscando uma alternativa, descobrimos, que a coleção de produtos utiliza uma reescrita da função getSelectCountSql (). Nós adaptamos e modificamos um pouco, o que terminou nesta solução:
Ele resolve os dois problemas que eu já mencionei e, tanto quanto posso ver, também funciona para os outros casos.
fonte