Magento2 category page pins the specified SKU product to the top of the list using dynamic URL parameters
There are several benefits to pinning specified SKU products to the top of the list using dynamic URL parameters:
-
Highlighting Products: Placing specific SKU products at the top makes them stand out, making them more likely to be noticed by users.
-
Promotions and Marketing: This feature can be utilized to promote specific products or sales events, enticing users to click and increase sales.
-
Increased Conversion Rates: Pinning popular or specific products at the top may increase their visibility and the likelihood of purchase as users browse, thus boosting conversion rates.
-
Customized User Experience: Through dynamic URL parameters, different SKU products can be prioritized based on specific user needs or behaviors, providing a more personalized user experience.
Overall, pinning specified SKU products to the top of the list through dynamic URL parameters can enhance product visibility, sales, and user experience, contributing to the optimization of e-commerce website operations.
Here are the steps to implement the functionality of pinning specified SKU products to the top of the list using dynamic URL parameters in Magento 2:
1. app/code/DMTQ/Catalog/etc/di.xml
<type name="Magento\Elasticsearch7\SearchAdapter\Mapper">
<plugin name="mapper_plugin" type="DMTQ\Catalog\Plugin\Elasticsearch\MapperPlugin" sortOrder="10"/>
</type>
2. app/code/DMTQ/Catalog/Plugin/Elasticsearch/MapperPlugin.php
namespace DMTQ\Catalog\Plugin\Elasticsearch;
use Magento\Elasticsearch7\SearchAdapter\Mapper;
use Magento\Framework\App\RequestInterface;
class MapperPlugin
{
/**
* Request
* @var RequestInterface
*/
protected RequestInterface $_request;
/**
* Class constructor
* @param RequestInterface $request
*/
public function __construct(
RequestInterface $request,
)
{
$this->_request = $request;
}
/**
* @param Mapper $subject
* @param $result
* @return array
*/
public function afterBuildQuery(
Mapper $subject,
$result
): array
{
$query = $result;
$skus = $this->getTopProductSkus();
if ($skus) {
$functionScoreQuery = [
'function_score' => [
'query' => [
'bool' => [
'should' => [
$query['body']['query'],
['terms' => ['sku.keyword' => $skus]]
]
]
],
'functions' => $this->filterWeight($skus),
'score_mode' => 'sum',
'boost_mode' => 'sum'
]
];
$query['body']['query'] = $functionScoreQuery;
$query['body']['sort'] = array_merge(['_score'], $query['body']['sort']);
}
return $query;
}
/**
* @param $skus
* @return array
*/
protected function filterWeight($skus): array
{
$weight = 100000;
$filters = [];
foreach ($skus as $sku) {
$filters[] = [
'filter' => [
'term' => [
'sku.keyword' => $sku
]
],
'weight' => $weight,
];
$weight = $weight - 1000;
}
return $filters;
}
/**
* @return array
*/
public function getTopProductSkus(): array
{
$skusStr = $this->_request->getParam('skus');
if (!$skusStr || strlen($skusStr) > 200) {
return [];
}
$skusStr = strtoupper($skusStr);
$skus = explode(',', $skusStr);
$skus = array_unique($skus);
if (count($skus) > 20) {
return [];
}
return $skus;
}
}