We have multi store configuration , all the store share the same product catalog. We filtering the collection based on the store and website. After removing some products from the collection grid displays all product in one page. but widget shows 3 pages. if click on the next page , page number will change to 2 but grid wont update. and if search for the product name , filter will show 1 record found. but grid will diplay all the products. Please help what is wrong with my collection.
<?php
protected function _prepareCollection()
{
$currentStoreId = $GLOBALS['STORE_ID'];
$store = $this->_getStore();
$currentWebsiteId = Mage::getModel('core/store')->load($currentStoreId)->getWebsiteId();
$collection = Mage::getModel('catalog/product')->getCollection()
->addAttributeToSelect('*');
if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
$collection->joinField('qty',
'cataloginventory/stock_item',
'qty',
'product_id=entity_id',
'{{table}}.stock_id=1',
'left');
}
foreach ($collection as $key => $product) {
$productVisibility = $this->getCurrentVisibility($product, $currentStoreId);
$productStoreId = $product->getData("product_creator_id");
$productWebsiteId = Mage::getModel('core/store')->load($productStoreId)->getWebsiteId();
if ($productWebsiteId == $currentWebsiteId) {
if ($productStoreId != $currentStoreId) {
$collection->removeItemByKey($product->getId());
} elseif ($currentWebsiteId != 4) {
if ($product->getData('product_type') == 11) { //enterprise == 11
if ($product->getData('share') == 0) {
$collection->removeItemByKey($product->getId());
}
}
}
}
}
if ($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);
$this->setCollection($collection);
if ($this->getCollection()) {
$this->_preparePage();
$columnId = $this->getParam($this->getVarNameSort(), $this->_defaultSort);
$dir = $this->getParam($this->getVarNameDir(), $this->_defaultDir);
$filter = $this->getParam($this->getVarNameFilter(), null);
if (is_null($filter)) {
$filter = $this->_defaultFilter;
}
if (is_string($filter)) {
$data = $this->helper('adminhtml')->prepareFilterString($filter);
$this->_setFilterValues($data);
}
else if ($filter && is_array($filter)) {
$this->_setFilterValues($filter);
}
else if(0 !== sizeof($this->_defaultFilter)) {
$this->_setFilterValues($this->_defaultFilter);
}
if (isset($this->_columns[$columnId]) && $this->_columns[$columnId]->getIndex()) {
$dir = (strtolower($dir)=='desc') ? 'desc' : 'asc';
$this->_columns[$columnId]->setDir($dir);
$this->_setCollectionOrder($this->_columns[$columnId]);
}
if (!$this->_isExport) {
$this->getCollection()->load();
$this->_afterLoadCollection();
}
}
return $this;
}
Best Answer
Anything you add to the collection after it is loaded has no effect on the collection.
When you do this
foreach ($collection as $key => $product) {
in order to remove some products the collection is loaded.And in your code the filters are applied after loading the collection.
Try to move your
removeItemByKey
code at the end, maybe implement the_afterLoadCollection
in the grid block.But I have a feeling that this won't solve your problem either. It will probably screw up the pagination.
Instead of using
removeItemByKey
you should try to exclude those products through filters.Something like
and come up with an other filter for the other condition. (I didn't really understand that).
Side note: Don't use
$GLOBALS['STORE_ID']
. It's ugly. Make use of theMage::register
andMage::registry
methods.