4
votes

When getting a product collection in Magento, I would expect the StoreFilter to do just that, filter by the current store. But I can't get it to work.

Say I have 2 stores set up like so: enter image description here

And both stores have a different root category. Main Store is the default sample data, Store2 has just one product I added. I would have thought that using the store filter, only products within the root category of the current store would show up. But I'm getting every product showing. I'm testing this by placing the following in my category view template:

$store_id = Mage::app()->getStore()->getId();
$_testproductCollection = Mage::getResourceModel('reports/product_collection')
->setStoreId($storeId)
->addStoreFilter($store_id)
->addAttributeToSelect('*');
$_testproductCollection->load();
foreach($_testproductCollection as $_testproduct){ 
echo $this->htmlEscape($_testproduct->getName()); 
};

If I echo the store ID, it's giving me the correct number. I have only one product in Store 2, so why am I getting every product from all stores returned? I can set every product in Main Store to not show in Store2 and then add a visibility filter, but that would take forever.

Also, I just noticed, if I echo the products store ID, I get the current ID, not the store it's assigned to:

echo $_testproduct->getStoreId()

What's going on?

UPDATE (April 8 2011): OK, so I tried joining the fields so that the store_id is included (as suggested below), the section of code {{table}}.store_id = 1 is just setting all the products to have a store_id of 1. How can I just get the store_id associated with the product?

$_testproductCollection = Mage::getResourceModel('catalog/product_collection');
$_testproductCollection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left');
$_testproductCollection->getSelect()->distinct(true);
$_testproductCollection->addAttributeToSelect('*')->load();

foreach($_testproductCollection as $_testproduct){  
echo $this->htmlEscape($_testproduct->getName())."<br/>"; 
echo "STORE IS ".$_testproduct->getData('store_id')."<br/>";
};

If I check the catalog_category_product_index table of my db, the store_id's are correct.

4
what version of magento?Jonathan Day
Is there any solution so far, having the same problem. I absolutely need the productcollection of a special storeview. I have one website, 4 storeviews (2 languages of 2 shops) which devide some categories and some not. Im new to magento so i do not understand the joinField() thing. Is there any example or another solution.user642813
See here - stackoverflow.com/questions/5078752/… - I ended up filtering by root category instead.Marlon Creative
Filtering by root is very buggy, so back to this now trying to figure out if it'll work...see above for updatesMarlon Creative
my solution for category filter by store ) [stackoverflow.com/a/19284088/1266559][1] [1]: stackoverflow.com/a/19284088/1266559Alex

4 Answers

4
votes

$_testproductCollection should look like this $_testproductCollection = Mage::getResourceModel('reports/product_collection')->addAttributeToSelect('*')->addStoreFilter().

If You print SELECT from that collection You will see that there ain't any store column, so addStoreFilter() can't apply WHERE.

You should use joinField() on Your collection and add store_id column from catalog_product_entity_varchar table.

EDIT

Sorry to keep You waiting ;)

$collection = Mage::getResourceModel('catalog/product_collection');
$collection->joinField('store_id', 'catalog_category_product_index', 'store_id', 'product_id=entity_id', '{{table}}.store_id = 1', 'left');
$collection->getSelect()->distinct(true);

This should do the trick, but just to be sure, please check if you're getting right products :)

3
votes

This worked for me:

Mage::app()->setCurrentStore($storeId); 
$productCollection = Mage::getModel('catalog/product')
            ->getCollection()
            ->addStoreFilter()
            ->addAttributeToSelect(array('sku','price'));
2
votes

OK, I think this works, haven't tested too much but seems to have done the trick. You need to first get your stores root category id, then join some fields so you have access to the products "category_id", then filter using that:

$_rootcatID = Mage::app()->getStore()->getRootCategoryId();

$_testproductCollection = Mage::getResourceModel('catalog/product_collection')
->joinField('category_id','catalog/category_product','category_id','product_id=entity_id',null,'left')
->addAttributeToFilter('category_id', array('in' => $_rootcatID))
->addAttributeToSelect('*');
$_testproductCollection->load();

foreach($_testproductCollection as $_testproduct){ 
    echo $this->htmlEscape($_testproduct->getName())."<br/>"; 
};
0
votes

I think

You don't need to do any joins as the magento's setStoreId() will work.

 $collection = Mage::getModel("catalog/product")
->getCollection()
->setStoreId(1) //change store Id according your needs
->addAttributeToSelect(array('name','url','sku'))
->setPageSize(20);                

This will get maximum 20 products from store id 1