5

I am working on my product collection query. I used "addWebsiteFilter" and "addStoreFilter" in my collection query. The problem is addWebsiteFilter supports array of website ids but addStoreFilter not supporting array of store ids so my query return error. Is any other method which supports array of store id for filtering product collection.

$collection_new = Mage::getModel('catalog/product')                          
->getCollection()           
->addAttributeToSelect(array('description','price'))
->addWebsiteFilter($web_id)
->addStoreFilter($storeId)
->addAttributeToFilter('status', 1);
2
  • Please put your query with your question so that we can review it. Oct 13, 2015 at 5:34
  • Question updated where $web_id is array of website ids and $storeId is array of store ids.
    – Mathew
    Oct 13, 2015 at 5:42

2 Answers 2

1

In magento, addStoreFilter() does not filter the collection by multiple stores . We are able to filter the product collection by one store only.

You can see.the logic at Mage_Catalog_Model_Resource_Product_Collection.

    public function addStoreFilter($store = null)
    {
        if ($store === null) {
            $store = $this->getStoreId();
        }
        $store = Mage::app()->getStore($store);

        if (!$store->isAdmin()) {
            $this->_productLimitationFilters['store_id'] = $store->getId();
            $this->_applyProductLimitations();
        }

        return $this;
    }

Magento does not have any function which will filter the collection by mutiple store id

1
  • How can i achieve this because i want to filter with multiple store ids.
    – Mathew
    Oct 13, 2015 at 6:30
0

Disclaimer : I didn't try this before. But you it will give you some ideas about how to achieve this functionality

By default, you can filter by multiple websites, but you can use only one store in the collection filter. If you need such functionality, then the only possible way is rewrite the class Mage_Catalog_Model_Resource_Product_Collection and modify following methods within your rewriting class

<?php
class Namespace_Module_odel_Resource_Product_Collection
    extends Mage_Catalog_Model_Resource_Product_Collection
{
    public function addStoreFilter($store = null)
    {
        $isAdmin = false;
        if (!is_array($store)) {
            $stores = array($this->getStoreId());
        }

        foreach ($stores as $store) {
            $stores = Mage::app()->getStore($store);
            if ($store->isAdmin()) {
                $isAdmin = true;
                break;
            }
        }

        if (!$isAdmin) {
            $this->_productLimitationFilters['store_id'] = $stores;
            $this->_applyProductLimitations();
        }

        return $this;
    }

    protected function _applyProductLimitations()
    {
        Mage::dispatchEvent('catalog_product_collection_apply_limitations_before', array(
            'collection'  => $this,
            'category_id' => isset($this->_productLimitationFilters['category_id'])
                ? $this->_productLimitationFilters['category_id']
                : null,
        ));
        $this->_prepareProductLimitationFilters();
        $this->_productLimitationJoinWebsite();
        $this->_productLimitationJoinPrice();
        $filters = $this->_productLimitationFilters;

        if (!isset($filters['category_id']) && !isset($filters['visibility'])) {
            return $this;
        }

        $conditions = array(
            'cat_index.product_id=e.entity_id',
            $this->getConnection()->quoteInto('cat_index.store_id IN(?)', $filters['store_id'])
        );
        if (isset($filters['visibility']) && !isset($filters['store_table'])) {
            $conditions[] = $this->getConnection()
                ->quoteInto('cat_index.visibility IN(?)', $filters['visibility']);
        }

        if (!$this->getFlag('disable_root_category_filter')) {
            $conditions[] = $this->getConnection()->quoteInto('cat_index.category_id = ?', $filters['category_id']);
        }

        if (isset($filters['category_is_anchor'])) {
            $conditions[] = $this->getConnection()
                ->quoteInto('cat_index.is_parent=?', $filters['category_is_anchor']);
        }

        $joinCond = join(' AND ', $conditions);
        $fromPart = $this->getSelect()->getPart(Zend_Db_Select::FROM);
        if (isset($fromPart['cat_index'])) {
            $fromPart['cat_index']['joinCondition'] = $joinCond;
            $this->getSelect()->setPart(Zend_Db_Select::FROM, $fromPart);
        }
        else {
            $this->getSelect()->join(
                array('cat_index' => $this->getTable('catalog/category_product_index')),
                $joinCond,
                array('cat_index_position' => 'position')
            );
        }

        $this->_productLimitationJoinStore();

        Mage::dispatchEvent('catalog_product_collection_apply_limitations_after', array(
            'collection' => $this
        ));

        return $this;
    }
}

Here we are doing two things.

  • We are rewriting the method addStoreFilter() in such a way that it will handle array data too. The function will just update the variable _productLimitationFilters['store_id'] and store the array value within it.

  • We are also rewriting the protected method _applyProductLimitations() here. The only change we are applying is this :

    $conditions = array(
            'cat_index.product_id=e.entity_id',
            $this->getConnection()->quoteInto('cat_index.store_id IN(?)', $filters['store_id'])
        );
    

    ie we are changing the condition in such a way that it will now handle an array of store ids.

Probably this will give you store array filtering functionality in Magento.


Rewriting would be the best approach in this case. But remember there is an event catalog_product_collection_apply_limitations_after which we can use to apply the same-thing. But it would be very difficult to do such array store filtering using this event. Because when this event get dispatched, magento is already applied the store filtering to the collection. So basically you need to remove that join from the collection first and then again need to apply your array filtering as you need. But it is a tough job

8
  • If i apply only this two changes then all products from both stores?If i do not change any thing catalog_product_collection_apply_limitations_after.
    – Mathew
    Oct 13, 2015 at 7:31
  • @Mathew the last part in my answer is for mentioning there is actually event exist which you can use if you have advanced knowledge in magento. Leave it. Go on with rewrite part which I mentined in my answer. you just try this Oct 13, 2015 at 7:38
  • Not Working. And it gives error in admin panel.
    – Mathew
    Oct 13, 2015 at 8:41
  • @Mathew what is the error? u're getting error only in adminside? Oct 13, 2015 at 8:58
  • Yes and it is also not working in my custom query.
    – Mathew
    Oct 13, 2015 at 9:00

Your Answer

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

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