I am working in Magento 2.4.1. I need to sort the products on list page and search result page with particular order. I want to display particular products first in all page(list and search). I have custom attribute "Sort". It has two options "Normal" and "Priority". I want to display normal products first everytime in search and list page.
Any simple way to do that ?
I did it with following way in magento 2.3 and it is working well. But in magento 2.4 due to elastic search not working.
I created dynamic module in backend from there user can select category, attribute and set the position. So it will be dynamicaly set. This part does not matter as I tried by static way but still it is not working.
What I did :
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">
<type name="Magento\Catalog\Model\Layer">
<plugin name="vendor_afterplugin_model_layer" type="vendor\module\Plugin\Layer" sortOrder="3" />
</type>
</config>
Layer.php
public function afterGetProductCollection(\Magento\Catalog\Model\Layer $subject, $result_main) {
// Here I will get the current category and its attribute with position which admin set from backend module
$objectManager = \Magento\Framework\App\ObjectManager::getInstance();
$request = $objectManager->get('Magento\Framework\App\Request\Http');
$_registry = $objectManager->get('\Magento\Framework\Registry');
$category = $_registry->registry('current_category');
if (empty($category)) {
$current_category_id = 0;
} else {
$attr_code = $request->getParam('product_list_order');
if (!isset($attr_code) || empty($attr_code)) {
$attr_code = $category->getDefaultSortBy();
}
$current_category_id = $category->getId();
}
$resource = $objectManager->get('Magento\Framework\App\ResourceConnection');
$connection = $resource->getConnection();
$tableName = $resource->getTableName('blue42_category_attribute_sort');
$sql = "Select * FROM " . $tableName . " where category_id=" . $current_category_id;
$results = $connection->fetchAll($sql);
$eavModel = $objectManager->create('Magento\Catalog\Model\ResourceModel\Eav\Attribute');
if (!empty($results)) {
foreach ($results as $key => $values) {
$attr = $eavModel->load($values['attribute_id']);
$attributeCode = $attr->getAttributeCode();
if (empty($category)) {
$attr_code = $attributeCode;
}
if ($attr_code == $attributeCode) {
$option_value_json = $values['option_id'];
$option_value_array = json_decode($option_value_json, true);
asort($option_value_array);
$order = [];
foreach ($option_value_array as $key => $value) {
$order[] = $key;
}
array_push($order, "");
$new_array = $result_main->getData();
// sort the array based on position
if (isset($attr_code)) {
usort($new_array, function ($a, $b) use ($order, $attr_code) {
$pos_a = array_search($a[$attr_code], $order);
$pos_b = array_search($b[$attr_code], $order);
return $pos_a - $pos_b;
});
$id_order = [];
foreach ($new_array as $key => $value_id) {
$id_order[] = $value_id['entity_id'];
}
// reset and sort the collection
$result_main->getSelect()->reset(\Magento\Framework\DB\Select::ORDER);
$result_main->getSelect()->order(new \Zend_Db_Expr("FIELD(e.entity_id, " . implode(",", $id_order) . ")"));
}
}
}
}
return $result_main;
}