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.xml
State 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