3

How to get product collection which is assigned to ONLY ONE STORE? This is not working by passing store ID to ->addStoreFilter();

Does have any idea?

6 Answers 6

5

If you want to select a product that is in a specific store and only in that specific store (not in the other stores), then this requires a bit more than only doing some filtering on the product collection.

First let me point out that products are connected to a website through their store, so the actual question is how to get a product from a website that is not in other websites...

Here's the code that should do the trick:

// 1. Get the store (current store or change the code to get
//    any other store or website)
$store = Mage::app()->getStore();

// 2. We need to get the IDs of the other websites
$otherWebsiteIds = Mage::getModel('core/website')->getCollection()
    ->addFieldToFilter('website_id', array('neq' => $store->getWebsiteId()))
    ->getAllIds();

// 3. Now we will build a query that is getting the product ID
//    from the catalog_product_website table where it is in the
//    other websites
$pw = Mage::getResourceModel('catalog/product_website');
$pwSubSelect = $pw->getReadConnection()->select()->from(['pw' => $pw->getMainTable()], 'product_id')
    ->where('pw.product_id = e.entity_id')->where('pw.website_id IN(?)', $otherWebsiteIds);

// 4. Now we're getting to the product collection...
//    Add your own filters here (for instance certain product IDs or categories)...
$collection = Mage::getModel('catalog/product')->getCollection();
$collection->addStoreFilter($store->getId());

// 5. Now let's say the product_id should not have any result in the
//    sub query of number 3. (so not be in the other websites)
$collection->getSelect()->where(
    'e.entity_id NOT IN(?)',
    new Zend_Db_Expr((string)$pwSubSelect)
);

This could result in an SQL query looking like this (here I have 3 websites and the current website has ID 3):

SELECT `e`.* FROM `catalog_product_entity` AS `e`
    INNER JOIN `catalog_product_website` AS `product_website`
        ON product_website.product_id = e.entity_id AND product_website.website_id = '3'
WHERE (e.entity_id NOT IN(
    SELECT `pw`.`product_id` FROM `catalog_product_website` AS `pw`
    WHERE (pw.product_id = e.entity_id) AND (pw.website_id IN('0', '1', '2'))
))
1
  • @7ochem I have one major doubt, in the table catalog_product_entity_varchar the entity_id corresponding store_id value is 0 actually, the value is 4, may i know why the value is 0.
    – Gem
    Mar 30, 2019 at 9:41
4

7ochems approach looks good, but here is another one ... don't know which performs better ...

$yourId = 5; # has to match websites default store ID
$storeIds = array();
foreach (Mage::app()->getWebsites() as $website) {
    $storeIds[] = $website->getDefaultStore()->getId();
}

$uniqueIds = array();
$dupeIds = array();

foreach ($storeIds as $storeId) {
    $products = Mage::getModel('catalog/product')
        ->getCollection()
        ->addStoreFilter($storeId);

    if ($yourId == $storeId) {
        $uniqueIds =  $products->getAllIds();
    } else {
        $dupeIds = array_unique(array_merge($dupeIds, $products->getAllIds()));
    }
}

$uniqueIds = array_diff($uniqueIds, $dupeIds);

// final collection
$products = Mage::getModel('catalog/product')
    ->getCollection()
    ->addIdFilter($uniqueIds);
6
  • 1
    This loops through all stores while products are linked on website level. So if I have 9 stores in 3 websites then this is looping 9 times while it should only have to loop 3 times
    – 7ochem
    Apr 12, 2018 at 14:30
  • 1
    @7ochem good catch ... changed to loop only over default stores.
    – sv3n
    Apr 12, 2018 at 14:40
  • Great idea. Now it will be more efficient. I would not use this approach though if the amount of products is very high. If you have 3 websites and 300k products of which 80% is in all 3 websites, then the $dupeIds array could become 720k items big. So if you only have a few products (maybe a few thousand), this is just fine...
    – 7ochem
    Apr 13, 2018 at 8:22
  • 1
    @7ochem ... moved array_unique() upwards, so max size is fixed by overall product count. 300k should not take sooo much memory. (?)
    – sv3n
    Apr 13, 2018 at 19:28
  • 1
    Very nice. It won't be a memory issue, probably more about time for processing a big array. Anyway the OP didn't explain the context, so there's not much to say about that
    – 7ochem
    Apr 15, 2018 at 9:30
0

Try this code:

$collection = Mage::getResourceModel('catalog/product_collection')->addStoreFilter(Mage::app()->getStore('store_id'));
2
  • 2
    Please do not add answers that are duplicates of other answers. Upvote other answers if you think those are right.
    – 7ochem
    Apr 12, 2018 at 13:10
  • 1
    This is fetching any product in that store and those products might also be in other stores, which was not the question of the OP. OP wants to find products that are in that specific store ONLY
    – 7ochem
    Apr 12, 2018 at 14:33
-1

Try to use this code :

$collection = Mage::getModel('catalog/product')->getCollection()->addFieldToFilter('store_id','enter store_id number');
1
  • 1
    This is fetching any product in that store and those products might also be in other stores, which was not the question of the OP. OP wants to find products that are in that specific store ONLY
    – 7ochem
    Apr 12, 2018 at 14:32
-1
$collection = Mage::getModel('catalog/product')->getCollection()
            ->setStoreId('your store id');
2
  • 1
    If you post code as an answer, please at least explain briefly what this code is doing and where it belongs. Answers with code but no explanation are rarely useful.
    – 7ochem
    Apr 12, 2018 at 13:09
  • 1
    This is fetching any product in that store and those products might also be in other stores, which was not the question of the OP. OP wants to find products that are in that specific store ONLY
    – 7ochem
    Apr 12, 2018 at 14:33
-1

Try this code :

$storeId=Mage::app()->getStore()->getStoreId();
$collection= Mage::getModel('catalog/product')->getCollection()->setStoreId($storeId);
2
  • 1
    Please do not add answers that are duplicates of other answers. Upvote other answers if you think those are right.
    – 7ochem
    Apr 12, 2018 at 14:19
  • 1
    This is fetching any product in that store and those products might also be in other stores, which was not the question of the OP. OP wants to find products that are in that specific store ONLY
    – 7ochem
    Apr 12, 2018 at 14:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.