Magento – $collection->getSize() will not apply to the filtered collection on category page; results in error

collection;filtermagento2

Experimenting with Magento EE 2.1.7. I've created a module which has the means to filter a collection but apparently I'm doing something wrong because I get an "Illegal State" error on the frontend category pages when I include this line prior to return $collection;

$collection->getSize();

While the below code will yield the desired result(s) in the category listing/grid, it fails to reflect the total number of results in pagination or the category product count in toolbar (i.e. There might be a single product on page but 600 products listed in the count and multiple pages of pagination).

<?php

// File: app/code/MyCompany/MyModule/Block/Category/Form.php

namespace MyCompany\MyModule\Block\Category;

class Form extends \Magento\Framework\View\Element\Template
{
    protected $_catalogLayer;

    public function __construct(
        \Magento\Framework\View\Element\Template\Context $context,
        \Magento\Catalog\Model\Layer\Resolver $layerResolver,
        array $data = []
    ) {
        $this->_catalogLayer = $layerResolver->get();
        parent::__construct($context, $data);
    }

    protected function _prepareLayout()
    {
        parent::_prepareLayout();

        $collection = $this->_catalogLayer->getProductCollection();

        $collection->addAttributeToFilter('sku', '123456');

        // This line results in "Illegal state" error on category page.
        $collection->getSize();

        return $collection;
    }
}

Best Answer

protected $_productCollectionFactory;

public function __construct(
...    
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $productCollectionFactory,
...
) {
$this->_productCollectionFactory = $productCollectionFactory;
}

Pass this class inside your __construct() method, and then:

$collection = $this->_productCollectionFactory->create();
$collection->addAttributeToFilter('sku', array('eq' => '123456'));
$size = $collection->getSize();
return $size;