I want to add extra sort options in backend these options are below
- All Sizes on top
- Minimum 1 sizes on top
- Top Discounted Product (discount percent)
and i have used this code to add other sort options here is my code.
etc/di.xml
<type name="Magento\VisualMerchandiser\Model\Sorting">
<plugin name="RLTSquare_VisualMerchandiser_Plugin_VisualMerchandiser_Model_SortingPlugin"
type="RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model\SortingPlugin" sortOrder="10"/>
</type>
\RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model\SortingPlugin.php
<?php
declare(strict_types=1);
namespace RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateBottom;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\MostPopular;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DiscountBottom;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DiscountTop;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\LowStockBottom;
use Magento\VisualMerchandiser\Model\Sorting;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
class SortingPlugin
{
/**
* @var SortInterface[]
*/
protected array $sortingOptions = [];
/**
* @param DateBottom $dateBottom
* @param DateTop $dateTop
* @param BestSelling $bestSelling
* @param MostPopular $mostPopular
* @param DiscountBottom $discountTop
* @param LowStockBottom $lowStockBottom
*/
public function __construct(
DateBottom $dateBottom,
DateTop $dateTop,
BestSelling $bestSelling,
MostPopular $mostPopular,
DiscountBottom $discountBottom,
DiscountTop $discountTop,
LowStockBottom $lowStockBottom
) {
$this->sortingOptions[20] = $dateBottom;
$this->sortingOptions[21] = $dateTop;
$this->sortingOptions[22] = $bestSelling;
$this->sortingOptions[23]= $mostPopular;
$this->sortingOptions[24]= $discountTop;
$this->sortingOptions[25]= $discountBottom;
$this->sortingOptions[26]= $lowStockBottom;
}
/**
* @param Sorting $subject
* @param array $result
* @return array
*/
public function afterGetSortingOptions(Sorting $subject, array $result): array
{
foreach ($this->sortingOptions as $idx => $instance) {
$result[$idx] = $instance->getLabel();
}
return $result;
}
/**
* @param Sorting $subject
* @param callable $callback
* @param $sortOption
* @return SortInterface
*/
public function aroundGetSortingInstance(Sorting $subject, callable $callback, $sortOption): SortInterface
{
if (isset($this->sortingOptions[$sortOption])) {
return $this->sortingOptions[$sortOption];
}
return $callback($sortOption);
}
}
\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\LowStockBottom.php
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;
use Magento\Framework\DB\Select;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\Exception\LocalizedException;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;
/**
* Rearrange product positions in category grid/tile view based on the stock ascending order
*/
class LowStockBottom extends SortAbstract implements SortInterface
{
const XML_PATH_MIN_STOCK_THRESHOLD = 'visualmerchandiser/options/minimum_stock_threshold';
/**
* Sort low stock on top for products in category
*
* @param Collection $collection
* @return Collection
* @throws LocalizedException
*/
public function sort(
Collection $collection
): Collection {
if (!$this->moduleManager->isEnabled('Magento_CatalogInventory')) {
return $collection;
}
$minStockThreshold = (int)$this->scopeConfig->getValue(self::XML_PATH_MIN_STOCK_THRESHOLD);
$baseSet = clone $collection;
$finalSet = clone $collection;
$collection->getSelect()
->having('stock <= ?', $minStockThreshold)
->reset(Zend_Db_Select::ORDER)
->order('stock ' . $collection::SORT_ORDER_DESC);
$resultIds = [];
$collection->load();
foreach ($collection as $item) {
$resultIds[] = $item->getId();
}
$ids = array_unique(array_merge($resultIds, $baseSet->getAllIds()));
$finalSet->getSelect()
->reset(Zend_Db_Select::ORDER)
->reset(Zend_Db_Select::WHERE);
$finalSet->addAttributeToFilter('entity_id', ['in' => $ids]);
if (count($ids)) {
$finalSet->getSelect()->order(new \Zend_Db_Expr('FIELD(e.entity_id, ' . implode(',', $ids) . ')'));
}
$finalSet->getSelect()
->reset(Zend_Db_Select::ORDER)
->order('stock ' . $finalSet::SORT_ORDER_DESC);
return $finalSet;
}
/**
* Get label for the Filter
*
* @return string
*/
public function getLabel(): string
{
return __("Move low stock to Bottom");
}
}
- By following this approch i want to add these sort options as you can see in picture above
- All Sizes on top
- Minimum 1 sizes on top
- Top Discounted Product (discount percent)
- How to do this any idea?