6

I'm working with a Magento flat collection I want to do this:

$collection = 'load a certain collection';
$collection->'addsomefilters';

if (count($collection) == 1) {
    //add some additional filters to the collection
}

return $collection;

Because I will call count() on my collection, the items from the database will be loaded, and even if I get into my if, when I will return it, the collection will have the same items before entering the if.

Is there a way to count my collection without having this behaviour, or can I reload the collection and apply my additional filters?

3 Answers 3

8

count() loads the collection, therefore it doesn't matter to reload it.

public function count()
{
    $this->load();
    return count($this->_items);
}

I can't find at this moment any way to reset the

/**
 * Loading state flag
 *
 * @var bool
 */
protected $_isCollectionLoaded;

but I'm sure there was a ($reload = false) flag somewhere in the collection.

If I'm wrong it is not possible what you want to do, if you don't extend the collection and reset the flag by yourself.

Find something which improves performance. To only count things you should use getSize() instead of count(), because it only queries for a COUNT(*). But still, I can't find any way to reset $_totalRecords.

/lib/Varien/Data/Collection/Db.php:208
/**
 * Get collection size
 *
 * @return int
 */
public function getSize()
{
    if (is_null($this->_totalRecords)) {
        $sql = $this->getSelectCountSql();
        $this->_totalRecords = $this->getConnection()->fetchOne($sql, $this->_bindParams);
    }
    return intval($this->_totalRecords);
}

/**
 * Get SQL for get record count
 *
 * @return Varien_Db_Select
 */
public function getSelectCountSql()
{
    $this->_renderFilters();

    $countSelect = clone $this->getSelect();
    $countSelect->reset(Zend_Db_Select::ORDER);
    $countSelect->reset(Zend_Db_Select::LIMIT_COUNT);
    $countSelect->reset(Zend_Db_Select::LIMIT_OFFSET);
    $countSelect->reset(Zend_Db_Select::COLUMNS);

    $countSelect->columns('COUNT(*)');

    return $countSelect;
}
3

can I reload the collection and apply my additional filters?

yes you can reset the loaded collection and apply more filters.

$collection->clear();

$collection->addFieldToFilter(....);

count($collection);

You can use clear method inside the if that to solve OP's problem:

$collection = 'load a certain collection';
$collection->'addsomefilters';

if (count($collection) == 1) {
    $collection->clear();
    //add original filters + additional filters to the collection
}

return $collection;
2
  • 1
    Please add an explanation of your code and how this will solve the OP's issue/question.
    – 7ochem
    Commented Nov 1, 2016 at 14:17
  • 1
    Magento\Framework\Data\Collection: public function clear() { $this->_setIsLoaded(false); $this->_items = []; return $this; }
    – Mammouth
    Commented Jan 19, 2018 at 12:21
0

If you applied filters, you can reload collection with :

$collection->clear()->getSelect()->reset(Zend_Db_Select::WHERE);

Your Answer

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

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