When building a special feature in Magento 2, one of the general requirements is to be displayed only certain products In the Category List page – although the category may contain more.

For example, maybe you just want to highlight a series of product IDs chosen by hand for campaigns or limiting visibility based on business rules.

Magento provides a flexible search and list mechanism Elasticsearch (in 2.4+).

To achieve this, we can intercept the request for search and inject our own Product id filter into the request of elasticsearch.

On this blog, I will guide you through how to do it step by step.

Step 1: Understand the flow

List of Magento Category Products Using Catalog search layer Internally, even when exploring the category. Kueri passed:

  • \Magento\CatalogSearch\Model\Search\RequestGenerator (Building search requests)
  • \Magento\Framework\Search\AdapterInterface::query() (Running the query in elasticsearch)

If we want to control which products appear, the cleanest way is to make A plugin at query() method from AdapterInterface. There we can inject us The product id that is permitted into request.

Step 2: Create a Special Module Framework

Let’s make a simple module, for example:
Vendor/CustomFilter

app/code/Vendor/CustomFilter/
├── etc
│   └── di.xml
├── Plugin
│   └── SearchAdapterPlugin.php
├── registration.php
└── etc/module.xml

Step 3: Determine the plugin in di.xml

In the etc/di.xmlState the plugin on AdapterInterface:

<?php
namespace Vendor\CustomFilter\Plugin;

use Magento\Framework\Search\RequestInterface;
use Magento\Elasticsearch\SearchAdapter\Aggregation\Builder as AggregationBuilder;
use Magento\Elasticsearch\SearchAdapter\ConnectionManager;
use Magento\Elasticsearch\SearchAdapter\ResponseFactory;
use Magento\Elasticsearch\ElasticAdapter\SearchAdapter\Mapper;
use Magento\Elasticsearch\SearchAdapter\QueryContainerFactory;

class SearchAdapterPlugin
{

     
    public function __construct(
        ConnectionManager $connectionManager,
        ResponseFactory $responseFactory,
        AggregationBuilder $aggregationBuilder,
        Mapper $mapper,
        QueryContainerFactory $queryContainerFactory,
        \Magento\Framework\App\RequestInterface $request,
        \Magento\Framework\App\ResourceConnection $resource
    ) {
        $this->connectionManager = $connectionManager;
        $this->responseFactory = $responseFactory;
        $this->aggregationBuilder = $aggregationBuilder;
        $this->mapper = $mapper;
        $this->queryContainerFactory = $queryContainerFactory;
        $this->request = $request;
        $this->connection = $resource->getConnection();
    }

    /**
     * Around plugin for Elasticsearch query
     */
    public function aroundQuery(
        \Magento\Framework\Search\AdapterInterface $subject,
        callable $proceed,
        RequestInterface $request
    ) {
        // Example: Allowed product IDs (could come from config, DB, or business logic)
        $allowedProductIds = [12, 34, 56, 78];

        $client = $this->connectionManager->getConnection();
        $aggregationBuilder = $this->aggregationBuilder;
        $updatedQuery = $this->mapper->buildQuery($request);

        if (!isset($updatedQuery['body']['query']['bool'])) {
            $updatedQuery['body']['query']['bool'] = [];
        }
        if (!isset($updatedQuery['body']['query']['bool']['filter'])) {
            $updatedQuery['body']['query']['bool']['filter'] = [];
        }

        $updatedQuery['body']['query']['bool']['filter'][] = ['ids' =>  ['values' => $allowedProductIds]];

        $aggregationBuilder->setQuery($this->queryContainerFactory->create(['query' => $updatedQuery]));
        
        $rawResponse = $client->query($updatedQuery);
        $rawDocuments = $rawResponse['hits']['hits'] ?? [];

        $queryResponse = $this->responseFactory->create(
                [
                    'documents' => $rawDocuments,
                    'aggregations' => $aggregationBuilder->build($request, $rawResponse),
                    'total' => $rawResponse['hits']['total']['value'] ?? 0
                ]
            );
        // Now proceed with modified query response
        return $queryResponse;
    }
}

This is what happened:

  • We define an Around the plugin For query()
  • Before continuing the request to Elasticsearch, we inject IDS filter
  • Elasticsearch then returned Only the product ID In the results

Step 5: Delete Cache & Test

Run the usual setting command:

bin/magento setup:
bin/magento cache:flush

Now visit any category page – instead of all products, you will only see the id [12, 34, 56, 78].


News
Berita
News Flash
Blog
Technology
Sports
Sport
Football
Tips
Finance
Berita Terkini
Berita Terbaru
Berita Kekinian
News
Berita Terkini
Olahraga
Pasang Internet Myrepublic
Jasa Import China
Jasa Import Door to Door

Kiriman serupa