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