Skip to main content
deleted 236 characters in body
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
<type name="Magento\VisualMerchandiser\Model\Sorting">
        <plugin name="RLTSquare_VisualMerchandiser_Plugin_VisualMerchandiser_Model_SortingPlugin"name="Vendor_Module_VisualMerchandiser_Plugin_VisualMerchandiser_Model_SortingPlugin"
                type="RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model\SortingPlugin"type="Vendor\Module\Plugin\VisualMerchandiser\Model\SortingPlugin" sortOrder="10"/>
    </type>

\RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model\SortingPlugin\Vendor\Module\Plugin\VisualMerchandiser\Model\SortingPlugin.php

<?php
declare(strict_types=1);

namespace RLTSquare\VisualMerchandiser\Plugin\VisualMerchandiser\Model;Vendor\Module\Plugin\VisualMerchandiser\Model;

use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateBottom;Vendor\Module\Model\VisualMerchandiser\Sorting\DateBottom;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop;Vendor\Module\Model\VisualMerchandiser\Sorting\DateTop;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling;Vendor\Module\Model\VisualMerchandiser\Sorting\BestSelling;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\MostPopular;Vendor\Module\Model\VisualMerchandiser\Sorting\MostPopular;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DiscountBottom;Vendor\Module\Model\VisualMerchandiser\Sorting\DiscountBottom;
use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DiscountTop;Vendor\Module\Model\VisualMerchandiser\Sorting\DiscountTop;

use RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\LowStockBottom;Vendor\Module\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\Vendor\Module\Model\VisualMerchandiser\Sorting\LowStockBottom.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;Vendor\Module\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");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop\Vendor\Module\Model\VisualMerchandiser\Sorting\DateTop.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;Vendor\Module\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\DB\Select;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

class DateTop extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $this->addPriceData($collection);
        $collection->getSelect()
            ->distinct('entity_id')
            ->reset(Zend_Db_Select::ORDER)
            ->order('created_at ' . CollectionAlias::SORT_ORDER_ASC);

        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Date to Top");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling\Vendor\Module\Model\VisualMerchandiser\Sorting\BestSelling.php

<?php

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;Vendor\Module\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Expr;
use Zend_Db_Select;

class BestSelling extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $connection = $collection->getConnection();
        $select = $connection->select()
            ->from($collection->getTable('sales_bestsellers_aggregated_yearly'), [
                'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
                'product_id'
            ])
            ->where('store_id = 0')
            ->group('product_id');
        $collection->getSelect()
            ->joinLeft(
                ['bs' => $select],
                'bs.product_id = e.entity_id'
            )
            ->reset(Zend_Db_Select::ORDER)
            ->order('bs.qty_ordered ' . Zend_Db_Select::SQL_DESC);
        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Best Selling");
    }
}
<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");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\DB\Select;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

class DateTop extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $this->addPriceData($collection);
        $collection->getSelect()
            ->distinct('entity_id')
            ->reset(Zend_Db_Select::ORDER)
            ->order('created_at ' . CollectionAlias::SORT_ORDER_ASC);

        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Date to Top");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling.php

<?php

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Expr;
use Zend_Db_Select;

class BestSelling extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $connection = $collection->getConnection();
        $select = $connection->select()
            ->from($collection->getTable('sales_bestsellers_aggregated_yearly'), [
                'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
                'product_id'
            ])
            ->where('store_id = 0')
            ->group('product_id');
        $collection->getSelect()
            ->joinLeft(
                ['bs' => $select],
                'bs.product_id = e.entity_id'
            )
            ->reset(Zend_Db_Select::ORDER)
            ->order('bs.qty_ordered ' . Zend_Db_Select::SQL_DESC);
        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Best Selling");
    }
}
<type name="Magento\VisualMerchandiser\Model\Sorting">
        <plugin name="Vendor_Module_VisualMerchandiser_Plugin_VisualMerchandiser_Model_SortingPlugin"
                type="Vendor\Module\Plugin\VisualMerchandiser\Model\SortingPlugin" sortOrder="10"/>
    </type>

\Vendor\Module\Plugin\VisualMerchandiser\Model\SortingPlugin.php

<?php
declare(strict_types=1);

namespace Vendor\Module\Plugin\VisualMerchandiser\Model;

use Vendor\Module\Model\VisualMerchandiser\Sorting\DateBottom;
use Vendor\Module\Model\VisualMerchandiser\Sorting\DateTop;
use Vendor\Module\Model\VisualMerchandiser\Sorting\BestSelling;
use Vendor\Module\Model\VisualMerchandiser\Sorting\MostPopular;
use Vendor\Module\Model\VisualMerchandiser\Sorting\DiscountBottom;
use Vendor\Module\Model\VisualMerchandiser\Sorting\DiscountTop;

use Vendor\Module\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);
    }
}

\Vendor\Module\Model\VisualMerchandiser\Sorting\LowStockBottom.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\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");
    }
}

\Vendor\Module\Model\VisualMerchandiser\Sorting\DateTop.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace Vendor\Module\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\DB\Select;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

class DateTop extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $this->addPriceData($collection);
        $collection->getSelect()
            ->distinct('entity_id')
            ->reset(Zend_Db_Select::ORDER)
            ->order('created_at ' . CollectionAlias::SORT_ORDER_ASC);

        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Date to Top");
    }
}

\Vendor\Module\Model\VisualMerchandiser\Sorting\BestSelling.php

<?php

namespace Vendor\Module\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Expr;
use Zend_Db_Select;

class BestSelling extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $connection = $collection->getConnection();
        $select = $connection->select()
            ->from($collection->getTable('sales_bestsellers_aggregated_yearly'), [
                'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
                'product_id'
            ])
            ->where('store_id = 0')
            ->group('product_id');
        $collection->getSelect()
            ->joinLeft(
                ['bs' => $select],
                'bs.product_id = e.entity_id'
            )
            ->reset(Zend_Db_Select::ORDER)
            ->order('bs.qty_ordered ' . Zend_Db_Select::SQL_DESC);
        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Best Selling");
    }
}
Notice removed Draw attention by Afzel Arshad
Bounty Ended with Victor Tihonchuk's answer chosen by Afzel Arshad
Notice added Draw attention by Afzel Arshad
Bounty Started worth 50 reputation by Afzel Arshad
added 3100 characters in body
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  4. Recently bought on top
<?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");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\DB\Select;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

class DateTop extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $this->addPriceData($collection);
        $collection->getSelect()
            ->distinct('entity_id')
            ->reset(Zend_Db_Select::ORDER)
            ->order('created_at ' . CollectionAlias::SORT_ORDER_ASC);

        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Date to Top");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling.php

<?php

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Expr;
use Zend_Db_Select;

class BestSelling extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $connection = $collection->getConnection();
        $select = $connection->select()
            ->from($collection->getTable('sales_bestsellers_aggregated_yearly'), [
                'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
                'product_id'
            ])
            ->where('store_id = 0')
            ->group('product_id');
        $collection->getSelect()
            ->joinLeft(
                ['bs' => $select],
                'bs.product_id = e.entity_id'
            )
            ->reset(Zend_Db_Select::ORDER)
            ->order('bs.qty_ordered ' . Zend_Db_Select::SQL_DESC);
        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Best Selling");
    }
}

These are some sorting options as example what i wants to ask

  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  4. Recently bought on top
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
<?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");
    }
}
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  4. Recently bought on top
<?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");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\DateTop.php

<?php
/**
 * Copyright © Magento, Inc. All rights reserved.
 * See COPYING.txt for license details.
 */

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Framework\Data\Collection as CollectionAlias;
use Magento\Framework\DB\Select;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Select;

class DateTop extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $this->addPriceData($collection);
        $collection->getSelect()
            ->distinct('entity_id')
            ->reset(Zend_Db_Select::ORDER)
            ->order('created_at ' . CollectionAlias::SORT_ORDER_ASC);

        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Date to Top");
    }
}

\RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting\BestSelling.php

<?php

namespace RLTSquare\VisualMerchandiser\Model\VisualMerchandiser\Sorting;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\VisualMerchandiser\Model\Sorting\SortAbstract;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;
use Zend_Db_Expr;
use Zend_Db_Select;

class BestSelling extends SortAbstract implements SortInterface
{
    /**
     * @param Collection $collection
     * @return Collection
     */
    public function sort(
        Collection $collection
    ): Collection {
        $connection = $collection->getConnection();
        $select = $connection->select()
            ->from($collection->getTable('sales_bestsellers_aggregated_yearly'), [
                'qty_ordered' => new Zend_Db_Expr('SUM(qty_ordered)'),
                'product_id'
            ])
            ->where('store_id = 0')
            ->group('product_id');
        $collection->getSelect()
            ->joinLeft(
                ['bs' => $select],
                'bs.product_id = e.entity_id'
            )
            ->reset(Zend_Db_Select::ORDER)
            ->order('bs.qty_ordered ' . Zend_Db_Select::SQL_DESC);
        return $collection;
    }

    /**
     * @return string
     */
    public function getLabel(): string
    {
        return __("Best Selling");
    }
}

These are some sorting options as example what i wants to ask

  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  4. Recently bought on top
deleted 26 characters in body
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (orignal price - special pricediscount percent)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (orignal price - special pricediscount percent)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (orignal price - special price)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (orignal price - special price)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
  1. All Sizes on top
  2. Minimum 1 sizes on top
  3. Top Discounted Product (discount percent)
deleted 104 characters in body
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
Loading
deleted 60 characters in body
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
Loading
Source Link
Afzel Arshad
  • 545
  • 3
  • 7
  • 38
Loading