1

I am using a basic product collection to get in-stock enabled product but it isn't returning all in-stock enabled products in my store. Please find the code below:

$Products =  Mage::getModel('catalog/product')->getCollection();
$Products->addAttributeToSelect('*');
$Products->addAttributeToFilter('status', 1);
Mage::getSingleton('cataloginventory/stock')->addInStockFilterToCollection($Products);
echo count($Products);

Its showing the count of 1964 records which is present in main website but total it must show 2003 records which is present including all stores.

I tried with filter $Products->addWebsiteFilter(array(1,2,3,4)); but still it returns the main website product count.

I tried this https://magento.stackexchange.com/questions/67893/product-collection-wont-get-all-productstoo, but not worked.

Also suggest some best query to fetch the collection,so that it not load the server.

Thanks

3
  • Mage::app()->setCurrentStore(0) didn't worked? That should load all products, the same as you see in Admin catalog product grid... Any difference if you do $Products->count() instead of count($Products)? Jan 15, 2019 at 9:16
  • Yes, I have tried with Mage::app()->setCurrentStore(0) but it throw error Fatal error: Call to undefined method Mage_Catalog_Model_Resource_Product_Flat::getType() in /domains/app/code/core/Mage/Eav/Model/Entity/Collection/Abstract.php on line 1087 Jan 15, 2019 at 9:20
  • Any difference if you do $Products->count() instead of count($Products)? both will return same result Jan 15, 2019 at 9:22

2 Answers 2

1

It seems your project has some problems working with collections, this can be caused by several things... so, let's try working with database. Even if you need to return product objects this would be (kindly, depending by the number of products in catalog) lighter & faster than working with collections

First, let's get the connection resource & implement some method to get attribute data in the class where you want to manage this

protected $_resource = null;

public function getResource()
{
    if (is_null($this->_resource)) {
        $this->_resource = Mage::getSingleton('core/resource');
    }
    return $this->_resource;
}

protected function _getAttribute($code)
{
    $readConnection = $this->getResource()->getConnection('core_read');
    $query = $readConnection->select()
        ->from($this->getResource()->getTableName('eav_attribute'))
        ->where('attribute_code = ?', $code);

    $results = $readConnection->fetchAll($query);
    if (!empty($results)) {
        return $results[0];
    }
    return false;
}

By default, status attribute has website scope (don't know if you have set it as Global in your project), so you need to select some website to filter by that attribute. If you want to get products enabled at least in one website you can implement some like this

protected function _isEnabled($productId)
{
    $attribute = $this->_getAttribute('status');
    $attributeId = $attribute['attribute_id'];

    $readConnection = $this->getResource()->getConnection('core_read');
    $query = $readConnection->select()
        ->from($this->getResource()->getTableName('catalog_product_entity_int'))
        ->where('attribute_id = ?', $attributeId)
        ->where('entity_id = ?', $productId)
        ->where('value = ?', Mage_Catalog_Model_Product_Status::STATUS_ENABLED);
        // you can implement additional website / store filter here

    $results = $readConnection->fetchAll($query);
    if (!empty($results)) {
        return true;
    }
    return false;
}

Let's assume stock management is enabled in the project, so all products must have some records in stock tables, so implement a method to get only in_stock products

protected function _isInStock($productId)
{
    $readConnection = $this->getResource()->getConnection('core_read');
    $query = $readConnection->select()
        ->from($this->getResource()->getTableName('cataloginventory_stock_item'))
        ->where('product_id = ?', $productId)
        ->where('is_in_stock = ?', 1);

    $results = $readConnection->fetchAll($query);
    if (!empty($results)) {
        return true;
    }
    return false;
}

Now, get all products in catalog product main table & apply the filters

$readConnection = $this->getResource()->getConnection('core_read');
$query = $readConnection->select()->from($this->getResource()->getTableName('catalog_product_entity'));
$results = $readConnection->fetchAll($query);
$products = array();
foreach ($results as $row){
    if (! $this->_isEnabled($row['entity_id'])){ continue; }
    if (! $this->_isInStock($row['entity_id'])){ continue; }
    // if you need to return product objects, load them
    // $products[] = Mage::getModel('catalog/product')->load($row['entity_id']);
    $products[] = $row['entity_id']; 
}
print_r(count($products));
6
0

Check if flat Catalog is enabled (System -> Configuration -> Catalog -> Catalog -> Frontend). If so disable it.

2
  • No, it will affect the performance. So can't disable the Flat Catalog Jan 15, 2019 at 6:37
  • Any other way ? Jan 15, 2019 at 7:06

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.