Is it possible to fetch the number of products matching the virtual category? I mean fo fetch (maybe collection or simple count products) if I have an instance of virtual category?
OS: Linux debian-8 3.16.0-4-amd64 #1 SMP Debian 3.16.39-1+deb8u2 (2017-03-07) x86_64 GNU/Linux
Magento Version: 2.1.4 CE
ElasticSuite Version: 2.3.3
Environment: developer
You can use Magento\Catalog\Model\Layer\Resolver :
$layer = $this->layerResolver->get();
$count = $layer->setCurrentCategory($category)->getProductCollection()->getSize();
@romainruaud, no, it's not working. It shows me 195 for each category when it's only six products in category.
Hmm you are right,
please try with Magento\CatalogSearch\Model\ResourceModel\Fulltext\CollectionFactory :
$collection = $this->collectionFactory()->create();
if ($category->getIsVirtualCategory() && $category->getVirtualRule()) {
$queryFilter = $category->getVirtualRule()->getCategorySearchQuery($category);
$collection->addQueryFilter($queryFilter);
} else {
$collection->addCategoryFilter($category);
}
$count = $collection->getSize();
Hmmm... I've got the next error:
Fatal error: Uncaught TypeError: Argument 3 passed to XXX\WidgetSubcategoryList\Block\Widget\Subcategories::__construct() must be an instance of Magento\CatalogSearch\Model\ResourceModel\Fulltext\CollectionFactory, instance of Magento\Catalog\Model\ResourceModel\Product\CollectionFactory given, called in /home/www/xxx/www/xxx.dev/vendor/magento/framework/ObjectManager/Factory/AbstractFactory.php on line 93 and defined in /home/www/xxx/www/xxx.dev/app/code/XXX/WidgetSubcategoryList/Block/Widget/Subcategories.php on line 41
I've checked the instance and deleted the var folder. But it still appears.
You are right, the factory is a virtual type and cannot therefore being injected directly.
You should have this :
block :
class Test extends \Magento\Framework\View\Element\Template
{
private $catalogLayer;
private $collectionFactory;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\Layer\Resolver $layerResolver,
\Magento\Catalog\Model\ResourceModel\Product\CollectionFactory $collectionFactory,
array $data
) {
$this->collectionFactory = $collectionFactory;
$this->catalogLayer = $layerResolver->get();
parent::__construct($context, $data);
}
protected function _prepareLayout()
{
$writer = new \Zend\Log\Writer\Stream(BP . '/var/log/rorua.log');
$logger = new \Zend\Log\Logger();
$logger->addWriter($writer);
$category = $this->catalogLayer->getCurrentCategory(); // Or anyway else to retrieve a category.
$collection = $this->collectionFactory->create();
if ($category->getIsVirtualCategory() && $category->getVirtualRule()) {
$queryFilter = $category->getVirtualRule()->getCategorySearchQuery($category);
$collection->addQueryFilter($queryFilter);
} else {
$collection->addCategoryFilter($category);
}
$count = $collection->getSize();
$logger->info(" Count : " . $count);
return parent::_prepareLayout();
}
}
di :
<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="\MyCodePool\Catalog\Block\Test">
<arguments>
<argument name="collectionFactory" xsi:type="object">Magento\CatalogSearch\Model\ResourceModel\Fulltext\CollectionFactory</argument>
</arguments>
</type>
</config>
@romainruaud now it works! Thank you so much!
@romainruaud hello!
I know this is an old post but I have the same issue and I'm using Magento 2.2.3
I followed your instructions but I get this error:
PHP Fatal error: Uncaught Error: Call to undefined method Magento\Catalog\Model\ResourceModel\Product\Collection\Interceptor::addQueryFilter() in /.../app/code/Vendor/Module/Block/VirtualCategories.php:78
Do you have any suggestion?
Thank you!
@romainruaud your code is working correctly only it not work when we call this from category_save after event catalog_category_save_after it returns the error No such entity with id = 0
Most helpful comment
You are right, the factory is a virtual type and cannot therefore being injected directly.
You should have this :
block :
di :