1

I want to show only Configurable products on listing page in magento 2. I have used the code " $_productCollection = clone $block->getLoadedProductCollection()->clear(); $_productCollection->addAttributeToFilter('type_id', array('eq' => 'configurable')); " in list.phtml file.

In frontend, i have applied pagination as well, to show 15 products first. See https://prnt.sc/3_iXFgV-FoQC But instead it shows only 6 products. https://prnt.sc/wMJUuEX72KNC According to my understanding , magento is applying filter on the 15 products count, which contains both simple and configurable products, and then it applies filter in these 15 products , and returns only 6 configurable products. Link http://discountedsunglasses.magento2e.com/women/sunglasses/aviator

note : This was working fine in magento 2.3. After i upgraded the site to magento 2.4 .It is not working properly. Please help. Its urgent.

9
  • I would like to clarify some information with you. 1. What types of products does your site use (Eg: Simple, Configurable, Bundle, Group...)? 2. Do you want to show only Configurable products on the search result page too?
    – Tu Van
    Nov 27, 2022 at 5:39
  • Yes, we are using Configurable products on entire site. We want to set simple product as "Catalog,search" but do not want to show then on listing page and search result page too. We only want to show configurable products. Nov 28, 2022 at 5:49
  • Could you tell me why you need to set simple products as “Catalog, Search”?
    – Tu Van
    Nov 28, 2022 at 5:57
  • Thats my clients requirement Nov 28, 2022 at 6:22
  • they ave set some url redirects which should work. You can check below 2 links. 1, discountedsunglasses.co.uk/… (working link). 2. discountedsunglasses.magento2e.com/arnette-sunglasses-dweet-d-3075-697-55-blue-rubber-dark-blue-blue-mirror (not working link). It should not redirect to catalog search page Nov 28, 2022 at 6:32

2 Answers 2

1
<?php
namespace Vendor\ModlueName\Model;

use Magento\Framework\Api\SearchCriteriaBuilder;
use Magento\Catalog\Api\ProductRepositoryInterface;

class ConfigurableProducts
{
    /** @var ProductRepositoryInterface */
    protected $productRepository;

    /** @var SearchCriteriaBuilder */
    protected $searchCriteriaBuilder;

    /**
     * Initialize dependencies.
     *
     * @param ProductRepositoryInterface $productRepository
     * @param SearchCriteriaBuilder $searchCriteriaBuilder
     */
    public function __construct(
        ProductRepositoryInterface $productRepository,
        SearchCriteriaBuilder $searchCriteriaBuilder
    ) {
        $this->productRepository = $productRepository;
        $this->searchCriteriaBuilder = $searchCriteriaBuilder;
    }

    /**
     * Get products with filter.
     * 
     * @return \Magento\Catalog\Api\Data\ProductInterface[]
     */
    public function getConfigurableProducts()
    {
        $searchCriteria = $this->searchCriteriaBuilder->addFilter('type_id', 'configurable', 'eq')->create();
        $products = $this->productRepository->getList($searchCriteria);
        return $products->getItems();
    }
}

call this function in listing page.

2
  • Are you overriding anything? Please give complete steps in detail Nov 3, 2022 at 11:19
  • This is not working. Nov 7, 2022 at 10:49
0

Since Magento 2.4 uses Elasticsearch,

  • to show only configurable products on the product listing page (category page) you need to override elasticsearchCategoryCollection virtualType which overrides Magento\CatalogSearch\Model\ResourceModel\Fulltext\CollectionFactory
  • to show only configurable products on the search result page you need to override elasticsearchFulltextSearchCollection virtualType which overrides Magento\CatalogSearch\Model\ResourceModel\Fulltext\SearchCollectionFactory

To achieve this, take the following steps:
Assume the Vendor name is TuVan and the module name is Catalog.

Step 1: Create registration.php:
File path: app/code/TuVan/Catalog/registration.php

<?php

use Magento\Framework\Component\ComponentRegistrar;

ComponentRegistrar::register(ComponentRegistrar::MODULE, 'TuVan_Catalog', __DIR__);

Step 2: Create module.xml:
File path: app/code/TuVan/Catalog/etc/module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="TuVan_Catalog">
        <sequence>
            <module name="Magento_CatalogSearch"/>
            <module name="Magento_Elasticsearch"/>
        </sequence>
    </module>
</config>

Step 3: Create di.xml:
File path: app/code/TuVan/Catalog/etc/frontend/di.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <virtualType name="elasticsearchCategoryCollection" type="TuVan\Catalog\Model\ResourceModel\Fulltext\Collection"/>
    <virtualType name="elasticsearchFulltextSearchCollection" type="TuVan\Catalog\Model\ResourceModel\Fulltext\Collection"/>
</config>

Step 4: Create Model\ResourceModel\Fulltext\Collection class.
File path: app/code/TuVan/Catalog/Model/ResourceModel/Fulltext/Collection.php

<?php

namespace TuVan\Catalog\Model\ResourceModel\Fulltext;

use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\DefaultFilterStrategyApplyCheckerInterface;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\TotalRecordsResolverFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierFactory;
use Magento\ConfigurableProduct\Model\Product\Type\Configurable;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Api\Search\SearchResultFactory;
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;

/**
 *
 *
 * Override to show only configurable products on product listing page and search result page
 *
 */
class Collection extends \Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection
{
    /**
     * @var string
     */
    private string $searchRequestName;

    /**
     * @param \Magento\Framework\Data\Collection\EntityFactory $entityFactory
     * @param \Psr\Log\LoggerInterface $logger
     * @param \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy
     * @param \Magento\Framework\Event\ManagerInterface $eventManager
     * @param \Magento\Eav\Model\Config $eavConfig
     * @param \Magento\Framework\App\ResourceConnection $resource
     * @param \Magento\Eav\Model\EntityFactory $eavEntityFactory
     * @param \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper
     * @param \Magento\Framework\Validator\UniversalFactory $universalFactory
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
     * @param \Magento\Framework\Module\Manager $moduleManager
     * @param \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState
     * @param \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig
     * @param \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory
     * @param \Magento\Catalog\Model\ResourceModel\Url $catalogUrl
     * @param \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate
     * @param \Magento\Customer\Model\Session $customerSession
     * @param \Magento\Framework\Stdlib\DateTime $dateTime
     * @param \Magento\Customer\Api\GroupManagementInterface $groupManagement
     * @param mixed $catalogSearchData
     * @param mixed $requestBuilder
     * @param mixed $searchEngine
     * @param mixed $temporaryStorageFactory
     * @param \Magento\Framework\DB\Adapter\AdapterInterface|null $connection
     * @param string $searchRequestName
     * @param SearchResultFactory|null $searchResultFactory
     * @param ProductLimitationFactory|null $productLimitationFactory
     * @param MetadataPool|null $metadataPool
     * @param \Magento\Search\Api\SearchInterface|null $search
     * @param \Magento\Framework\Api\Search\SearchCriteriaBuilder|null $searchCriteriaBuilder
     * @param \Magento\Framework\Api\FilterBuilder|null $filterBuilder
     * @param SearchCriteriaResolverFactory|null $searchCriteriaResolverFactory
     * @param SearchResultApplierFactory|null $searchResultApplierFactory
     * @param TotalRecordsResolverFactory|null $totalRecordsResolverFactory
     * @param DefaultFilterStrategyApplyCheckerInterface|null $defaultFilterStrategyApplyChecker
     * @SuppressWarnings(PHPMD.ExcessiveParameterList)
     * @SuppressWarnings(PHPMD.NPathComplexity)
     * @SuppressWarnings(PHPMD.UnusedFormalParameter)
     */
    public function __construct(
        \Magento\Framework\Data\Collection\EntityFactory $entityFactory,
        \Psr\Log\LoggerInterface $logger,
        \Magento\Framework\Data\Collection\Db\FetchStrategyInterface $fetchStrategy,
        \Magento\Framework\Event\ManagerInterface $eventManager,
        \Magento\Eav\Model\Config $eavConfig,
        \Magento\Framework\App\ResourceConnection $resource,
        \Magento\Eav\Model\EntityFactory $eavEntityFactory,
        \Magento\Catalog\Model\ResourceModel\Helper $resourceHelper,
        \Magento\Framework\Validator\UniversalFactory $universalFactory,
        \Magento\Store\Model\StoreManagerInterface $storeManager,
        \Magento\Framework\Module\Manager $moduleManager,
        \Magento\Catalog\Model\Indexer\Product\Flat\State $catalogProductFlatState,
        \Magento\Framework\App\Config\ScopeConfigInterface $scopeConfig,
        \Magento\Catalog\Model\Product\OptionFactory $productOptionFactory,
        \Magento\Catalog\Model\ResourceModel\Url $catalogUrl,
        \Magento\Framework\Stdlib\DateTime\TimezoneInterface $localeDate,
        \Magento\Customer\Model\Session $customerSession,
        \Magento\Framework\Stdlib\DateTime $dateTime,
        \Magento\Customer\Api\GroupManagementInterface $groupManagement,
        $catalogSearchData = null,
        $requestBuilder = null,
        $searchEngine = null,
        $temporaryStorageFactory = null,
        \Magento\Framework\DB\Adapter\AdapterInterface $connection = null,
        $searchRequestName = 'catalog_view_container',
        SearchResultFactory $searchResultFactory = null,
        ProductLimitationFactory $productLimitationFactory = null,
        MetadataPool $metadataPool = null,
        \Magento\Search\Api\SearchInterface $search = null,
        \Magento\Framework\Api\Search\SearchCriteriaBuilder $searchCriteriaBuilder = null,
        \Magento\Framework\Api\FilterBuilder $filterBuilder = null,
        SearchCriteriaResolverFactory $searchCriteriaResolverFactory = null,
        SearchResultApplierFactory $searchResultApplierFactory = null,
        TotalRecordsResolverFactory $totalRecordsResolverFactory = null,
        DefaultFilterStrategyApplyCheckerInterface $defaultFilterStrategyApplyChecker = null
    ) {
        parent::__construct(
            $entityFactory,
            $logger,
            $fetchStrategy,
            $eventManager,
            $eavConfig,
            $resource,
            $eavEntityFactory,
            $resourceHelper,
            $universalFactory,
            $storeManager,
            $moduleManager,
            $catalogProductFlatState,
            $scopeConfig,
            $productOptionFactory,
            $catalogUrl,
            $localeDate,
            $customerSession,
            $dateTime,
            $groupManagement,
            $catalogSearchData,
            $requestBuilder,
            $searchEngine,
            $temporaryStorageFactory,
            $connection,
            $searchRequestName,
            $searchResultFactory,
            $productLimitationFactory,
            $metadataPool,
            $search,
            $searchCriteriaBuilder,
            $filterBuilder,
            $searchCriteriaResolverFactory,
            $searchResultApplierFactory,
            $totalRecordsResolverFactory,
            $defaultFilterStrategyApplyChecker
        );
        $this->searchRequestName = $searchRequestName;
    }

    /**
     * @inheritdoc
     *
     * Override to show only configurable products on product listing page and search result page
     */
    protected function _renderFiltersBefore()
    {
        $applyCustomFilterToSearchRequests = ['catalog_view_container', 'quick_search_container'];
        if (in_array($this->searchRequestName, $applyCustomFilterToSearchRequests)) {
            $this->addAttributeToFilter('type_id', Configurable::TYPE_CODE);
        }

        parent::_renderFiltersBefore();
    }
}

Step 5: Install the module: bin/magento setup:upgrade

Step 6: Compile code: bin/magento setup:di:compile

Step 7: Deploy static content: bin/magento setup:static-content:deploy -f

You are done.

3
  • Hi , this is not working for me. Have you added all the files and all the code? Jan 2 at 10:08
  • Hi, Yes, which part is not working for you? I tested it before sharing it with you! My code allows your site able to show only configurable products on product listing page and catalog search result page.
    – Tu Van
    Jan 2 at 10:19
  • If you apply my code and assume 1. there are no modules overriding elasticsearchCategoryCollection and elasticsearchFulltextSearchCollection 2. Or no modules overriding Magento\CatalogSearch\Model\ResourceModel\Fulltext\CollectionFactory and Magento\CatalogSearch\Model\ResourceModel\Fulltext\SearchCollectionFactory 3. Or you are not using other search extensions.
    – Tu Van
    Jan 2 at 10:20

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.