Речь пойдет о коллекции продуктов, которые выводятся в листинге категории или например, в результатах поиска. Предположим, что коллекция получена следующим образом:
$collection = Mage::getModel('catalog/product')->getCollection()
Что же можно сделать…
1. Добавим дополнительный аттрибут, чтобы потом сделать по нему выборку:
$collection->addAttributeToSelect('attribute_name');
Правда в этом случае аттрибут по умолчанию добавится с условие INNER JOIN. И в выборку попадут только те товары, для которых значение аттрибута явно задано. Чтобы наличие значения не оказывало влияние на выборку, атррибут надо добавлять с условием LEFT JOIN. Это надо задать явно:
$collection->addAttributeToSelect('attribute_name', 'left');
2. Включим в выборку факт наличие товара на складе (In Stock).
$collection->joinField('qty', 'cataloginventory/stock_item', 'qty', 'product_id=entity_id', null, 'left');
Правда у этого метода есть одно ограничение. Он работает только для простых (Simple) товаров. Для сложных/составных (Configurable) продуктов он будет показывать 0.
3. Получим список id составных товаров, которые есть в наличии:
Для этого проще и быстрей всего выполнить прямой запрос к базе данных Magento
$resource = Mage::getSingleton('core/resource'); $readConnection = $resource->getConnection('core_read'); $SQL = "SELECT DISTINCT r.parent_id AS id FROM ".$resource->getTableName('catalog/product_relation'). " AS r"; $SQL .= " LEFT JOIN ".$resource->getTableName('cataloginventory/stock_item')." AS s ON r.child_id=s.product_id"; $SQL .= " WHERE r.parent_id IN "; $SQL .= "(SELECT product_id FROM ".$resource->getTableName('catalog/category_product_index'); $SQL .= " WHERE category_id=".$this->getCurrentCategory()->getId().")"; $SQL .= " AND s.qty >0"; $ids = $readConnection->fetchAll($SQL);
4. Сформируем сложный запрос на выборку:
$collection->addFieldToFilter(array( array('attribute' => 'attribute_name', 'eq'=>1), array('attribute' => 'qty', 'gt' => 0), array('attribute' => 'entity_id', 'in'=>$ids) ));
Указанный запрос формирует WHERE с условием OR. И в этом случае в выборку попадают все товары которые есть в наличии (In stock) либо у которых атрибут attribute_name имеет значение равное 1.
Для того чтобы запрос работал именно так, в настройках магазина должен быть включен вывод всех товаров в независимости от их наличия на складе (Show out stock).
Аналогичным способом можно добавлять другие аттрибуты, либо использовать другие условия. Формируемый запрос всегда можно посмотреть и проверить:
echo($collection->getSelect());