Magento 2 Filter Product Collection by Store ID – How to Guide

collection;magento2PHP

Using a product factory object, I'm able to create a product, grab a product collection, and fetch the first item of that collection

/* var $productFactory \Magento\Catalog\Model\ProductFactory */
$product = $this->productFactory->create()->getCollection()->getFirstItem();

However, if I attempt to add a store_id to the collection's filter

    $product = $this->productFactory
        ->create()
        ->getCollection()
        ->addFieldToFilter('store_id', 1)
        ->getFirstItem();

I get the following error

Invalid attribute name: store_id
#0 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(1434): Magento\Eav\Model\Entity\Collection\AbstractCollection->_addAttributeJoin('store_id', 'inner')
#1 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(359): Magento\Eav\Model\Entity\Collection\AbstractCollection->_getAttributeConditionSql('store_id', 1, 'inner')
#2 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Catalog/Model/Resource/Product/Collection.php(1489): Magento\Eav\Model\Entity\Collection\AbstractCollection->addAttributeToFilter('store_id', 1, 'inner')
#3 /Users/alanstorm/Sites/magento-2-dev-docs.dev/magento2/app/code/Magento/Eav/Model/Entity/Collection/AbstractCollection.php(382): Magento\Catalog\Model\Resource\Product\Collection->addAttributeToFilter('store_id', 1)
...
#63 {main}

The same thing happens if I attempt to use a product repository to filter by store_id (the repositories use the collections under the hood).

Is this a bug? Or has the relationships between stores, websites, and products changed in Magento 2 such that that this is no longer a legitimate query? Both? Neither? Something else?

Best Answer

You can do this with the method addStoreFilter(), see Magento\Catalog\Model\ResourceModel\Product\Collection#addStoreFilter()

the addStoreFilter() function will accept store ID or Store object as a parameter.

EG, to get all products for the current store:

public function getProducts(){
    return $this->collection->addStoreFilter($this->_storeManager->getStore()); 
}

Hopefully, this helps.

Related Topic