Pracuję na siatce produktów, ale podział na strony lub liczba produktów nie działa (ponieważ wyświetla niepoprawną liczbę). ponieważ moja funkcja blokowania _preparecollection jest jak poniżej. dodałem kod filtru kategorii w kolekcji, więc muszę użyć klauzuli grupy, aby zapobiec wystąpieniu błędu dla tego samego identyfikatora.
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;
}
Miałem google, otrzymałem odpowiedź i dodałem ją do 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;
}
Ale nie powodzenia, pomóżcie rozwiązać ten problem
magento-1.9
collection
collection-filtering
grid
Zaheerabbas
źródło
źródło
Mage_Adminhtml_Block_Widget_Grid
?Mage_Adminhtml_Block_Widget_Grid
Odpowiedzi:
Kolekcje i Leniwe Ładowanie w Magento
Nie działa podział na strony, ponieważ liczone są kolekcje i jak działa leniwe ładowanie kolekcji.
Kolekcje w Magento implementują klasę
Countable
. Ze względu na leniwe ładowanie kolekcji w Magento, przy każdymcount()
wywołaniu metody dane muszą zostać załadowane. Aby obejść ten problem, kolekcje implementują metodę o nazwiegetSize()
. Sklonuje twoją instrukcję SQL, owinie jąCOUNT()
i zwróci wynik. To pozwoliło kolekcji uzyskać całkowitą liczbę bez ładowania wszystkich danych. Pozwala to na dodanie takich elementów jak filtry w ostatniej chwili.Oto jak wygląda
Varien_Data_Collection_Db::getSize()
jego partnergetSelectCountSql()
:Zasadniczo porzuca limity, kolumny, kolejność itp. I pozostawia filtry. Następnie dodaje MySQL
COUNT()
do kolumn.Problem
Zwykle w przypadku jednej tabeli zwracany byłby jeden wiersz z całkowitą liczbą. Dlatego
getSize()
robi tofetchOne()
przeciwko zapytaniu. Jednak podczas wykonywania takich czynności, jak łączenia tabel, grupowania, itp., Nie zwrócisz jednego wiersza, zwrócisz wiele. Z tego powodu musisz zmienićgetSize()
metodę w swojej kolekcji.Rozwiązanie
Tak powinna teraz wyglądać Twoja metoda:
Zamiast a
fetchOne()
uruchomiliśmyfetchAll()
zawiniętą funkcjęcount()
PHP. Teraz sumy zostaną odpowiednio zwrócone.źródło
Świetne rozwiązanie. Może ktoś ma taki sam problem jak my, więc opublikuję inne możliwe rozwiązanie. W naszym przypadku mieliśmy kolekcję, która czasami zawierała grupę według instrukcji, a czasem nie, w zależności od siatki, w której kolekcja została załadowana. Korzystając z powyższego rozwiązania, znaleźliśmy dwa problemy:
Po debugowaniu chwilę okazało się, że w przypadku 1 część
zwraca tablicę, która ma jeden wpis o wartości 0. Dlatego funkcja count zwraca 1, chociaż nie znaleziono żadnych wpisów.
W przypadku 2 ta sama część zwraca tablicę z jednym wpisem, którego wartością jest rzeczywisty rozmiar kolekcji. Funkcja liczenia ponownie zwraca 1, a nie wartość.
Szukając alternatywy, dowiedzieliśmy się, że kolekcja produktów korzysta z przepisania funkcji getSelectCountSql (). Dostosowaliśmy to i nieco zmieniliśmy, co zakończyło się tym rozwiązaniem:
Rozwiązuje dwa problemy, o których już wspomniałem i, o ile widzę, działa również w innych przypadkach.
źródło