3

In magento enterprise edition, in admin catalog/category there are sort options which sort products on storefront based on that filter, now i want to add a custom filter like Filter by Product Creation date ascending and descending order and on category page the products should sort by date of creation. enter image description here

For Example i want to add two filter or sort option in this menu like sort by Product creation date ASC and DESC wise and products below this grid or storefront display according to this sort option. Thanks in advance. this option is only available in magento Enterprise edition

2 Answers 2

4

First of all, in situations when you can use plugin or observer it's always better than use preference.

Your issue is related to you didn't define your sortInstances and only add options. You defined getSortingOptions but for processing used first available (\Magento\VisualMerchandiser\Model\Sorting\UserDefined)

app/code/Acme/StackExchange/etc/adminhtml/di.xml

<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
    <type name="Magento\VisualMerchandiser\Model\Sorting">
        <plugin name="Acme_StackExchange_Plugin_VisualMerchandiser_Model_SortingPlugin"
                type="Acme\StackExchange\Plugin\VisualMerchandiser\Model\SortingPlugin" sortOrder="10"/>
    </type>
</config>

app/code/Acme/StackExchange/Plugin/VisualMerchandiser/Model/SortingPlugin.php

<?php
declare(strict_types=1);

namespace Acme\StackExchange\Plugin\VisualMerchandiser\Model;

use Acme\StackExchange\Model\VisualMerchandiser\Sorting\DateBottom;
use Magento\VisualMerchandiser\Model\Sorting;
use Magento\VisualMerchandiser\Model\Sorting\SortInterface;

class SortingPlugin
{
    /**
     * @var SortInterface[]
     */
    protected array $sortingOptions = [];

    public function __construct(
        DateBottom $dateBottom
    ) {
        $this->sortingOptions[20] = $dateBottom;
    }

    public function afterGetSortingOptions(Sorting $subject, array $result): array
    {
        foreach ($this->sortingOptions as $idx => $instance) {
            $result[$idx] = $instance->getLabel();
        }

        return $result;
    }

    public function aroundGetSortingInstance(Sorting $subject, callable $callback, $sortOption): SortInterface
    {
        if (isset($this->sortingOptions[$sortOption])) {
            return $this->sortingOptions[$sortOption];
        }

        return $callback($sortOption);
    }
}
3
  • Bro if its not too much to ask ,can you take a look at my question, i just thought you may know the answer. here is my question magento.stackexchange.com/questions/358034/… Commented Jul 20, 2022 at 16:18
  • What does the first sentence mean? That Plugins are better to use than Observers?
    – dotancohen
    Commented Aug 8, 2022 at 12:58
  • No. This is means that when you can use plugin or observer it's always better than preference. Commented Aug 8, 2022 at 13:05
0

I also tried making a custom option but i was unable to sort it according to my filters here is my code

etc/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">
    <preference for="Magento\VisualMerchandiser\Model\Sorting" type="Vendor\Module\Model\Filters"/>
</config>

model/filters.php

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

namespace Vendor\Module\Model;

use Magento\VisualMerchandiser\Model\Sorting;

/**
 * Sort the product collection
 *
 * @api
 * @since 100.0.2
 */
class Filters extends Sorting
{
    /**
     * Get available sorting options
     *
     * @return array
     */
    public function getSortingOptions(): array
    {
        $options = [];
        foreach ($this->sortInstances as $idx => $instance) {
            $options[$idx] = $instance->getLabel();
        }
        array_push($options, 'DateBottom', 'DateTop','SpecialPriceMiddle');
        return $options;
    }
}

Model/Sorting/DateBottom.php

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

namespace Vendor\Module\Model\Sorting;

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

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

        return $collection;
    }

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

here is one of three option i added in this sort option filter but its not sorting in this grid below picture nor frontend. any solutions? enter image description here

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.