Magento 2 Cara menambahkan opsi urutkan berdasarkan pilihan


22

Saya perlu menambahkan filter tambahan berdasarkan created_atatribut untuk menyortir daftar produk berdasarkan produk terbaru. Saya mencoba mencari menggunakan file di bawah ini

app/design/frontend/Vendor/ThemeName/Magento_Catalog/templates/product/list/toolbar/sorter.phtml  

tetapi bagaimana cara menambahkan id entitas kita getAvailableOrders()?

Jawaban:


23

Jika Anda ingin menggunakan atribut seperti created_atitu tidak ada di admin-> toko -> (atribut) produk, karena atribut yang didefinisikan dalam admin memiliki pengaturan Sorting in Product Listing = Yes/No, Anda harus bekerja dengan dua file ini:

\vendor\magento\module-catalog\Block\Product\ProductList\Toolbar.php \vendor\magento\module-catalog\Model\Config.php

Di dalam Toolbar.phpkamu bisa melihat

$this->_availableOrder = $this->_catalogConfig->getAttributeUsedForSortByArray();

itu panggilan getAttributeUsedForSortByArray()dari Config.phpyang mengembalikan berbagai atribut yang tersedia untuk mengurutkan koleksi daftar.

Sekarang, Anda harus menambahkan created_atatribut Anda di sini. Bagaimana? Saya melakukannya dengan sebuah plugin

/**
 * Add sort order option created_at to frontend
 */
public function afterGetAttributeUsedForSortByArray(
    \Magento\Catalog\Model\Config $catalogConfig,
    $options
) {
    $options['created_at'] = __('New');
    return $options;
}

Anda memasukkan created_atatribut yang tersedia untuk disortir, sekarang Anda hanya perlu membangun koleksi khusus untuk menggunakannya. Di sini saya memilih untuk menimpa \vendor\magento\module-catalog\Block\Product\ProductList\Toolbar.php dengan milik saya Toolbar.phpdan menimpanyasetCollection()

/**
 * Set collection to pager
 *
 * @param \Magento\Framework\Data\Collection $collection
 * @return $this
 */
 public function setCollection($collection) {
    $this->_collection = $collection;
    $this->_collection->setCurPage($this->getCurrentPage());

    // we need to set pagination only if passed value integer and more that 0
    $limit = (int)$this->getLimit();
    if ($limit) {
        $this->_collection->setPageSize($limit);
    }

    // switch between sort order options
    if ($this->getCurrentOrder()) {
        // create custom query for created_at option
        switch ($this->getCurrentOrder()) {
            case 'created_at':
                if ($this->getCurrentDirection() == 'desc') {
                    $this->_collection
                        ->getSelect()
                        ->order('e.created_at DESC');
                } elseif ($this->getCurrentDirection() == 'asc') {
                    $this->_collection
                        ->getSelect()
                        ->order('e.created_at ASC');           
                }
                break;
            default:
                $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
                break;
        }
    }

    // echo '<pre>';
    // var_dump($this->getCurrentOrder());
    // var_dump((string) $this->_collection->getSelect());
    // die;

    return $this;        
}

Itu saja, bagi saya bekerja seperti pesona.


Jika ada yang ingin secara default naik, maka ubah } elseif ( $this->getCurrentDirection() == 'asc' ) {ke } else {.
thdoan

2
Selain itu, jika Anda tidak ingin menggunakan plugin, Anda juga dapat menggunakan fungsi publik $block->addOrderToAvailableOrders('created_at', 'New')bawaan di templat penyortir Anda.
thdoan

Bisakah Anda memiliki solusi untuk menyortir harga produk khusus? @Luca
Dhaduk Mitesh

@DhadukMitesh yakin, Anda bisa menggunakan kode di atas dan mengubah kode atribut created_atdengan kode atribut harga khusus Anda
LucScu

Saya tidak memiliki atribut harga khusus. Saya menggunakan harga standar berdasarkan. Saya hanya mengubah file inti di mana harga disortir. dan saya ingin menetapkan harga khusus untuk koleksi. tapi saya tidak bisa menetapkan harga khusus dalam koleksi.
Dhaduk Mitesh

19

Kita dapat mencapainya dengan menggunakan Plugin. Silakan buat file berikut di modul Anda.

app / code / Package / CustomToolbar / etc / di.xml

<type name="Magento\Catalog\Model\Config">
    <plugin name="Package_CustomToolbar::addCustomOptions" type="Package\CustomToolbar\Plugin\Model\Config" />
</type>
<type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
    <plugin name="Package_CustomToolbar::addPriceDecendingFilterInToolbar" type="Package\CustomToolbar\Plugin\Product\ProductList\Toolbar" />
</type>

app / code / Package / CustomToolbar / Plugin / Model / Config.php

namespace Package\CustomToolbar\Plugin\Model;
use Magento\Store\Model\StoreManagerInterface;
class Config
{
    protected $_storeManager;

public function __construct(
    StoreManagerInterface $storeManager
) {
    $this->_storeManager = $storeManager;

}

/**
 * Adding custom options and changing labels
 *
 * @param \Magento\Catalog\Model\Config $catalogConfig
 * @param [] $options
 * @return []
 */
public function afterGetAttributeUsedForSortByArray(\Magento\Catalog\Model\Config $catalogConfig, $options)
{
    $store = $this->_storeManager->getStore();
    $currencySymbol = $store->getCurrentCurrency()->getCurrencySymbol();

    //Remove specific default sorting options
    unset($options['position']);
    unset($options['name']);
    unset($options['price']);

    //Changing label
    $customOption['position'] = __('Relevance');

    //New sorting options
    $customOption['price_desc'] = __($currencySymbol.' (High to Low)');
    $customOption['price_asc'] = __($currencySymbol.' (Low to High)');

    //Merge default sorting options with custom options
    $options = array_merge($customOption, $options);

    return $options;
}
}

app / kode / Paket / CustomToolbar / Plugin / Produk / ProductList / Toolbar.php

namespace Package\CustomToolbar\Plugin\Product\ProductList;
class Toolbar
{
    /**
     * Plugin
     *
     * @param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
     * @param \Closure $proceed
     * @param \Magento\Framework\Data\Collection $collection
     * @return \Magento\Catalog\Block\Product\ProductList\Toolbar
     */
    public function aroundSetCollection(
        \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
        \Closure $proceed,
        $collection
    ) {
        $currentOrder = $subject->getCurrentOrder();
        $result = $proceed($collection);

        if ($currentOrder) {
            if ($currentOrder == 'price_desc') {
                $subject->getCollection()->setOrder('price', 'desc');
            } elseif ($currentOrder == 'price_asc') {
                $subject->getCollection()->setOrder('price', 'asc');
            }
        }

        return $result;
    }
}

Ini bekerja dengan baik untuk saya tanpa menulis ulang kelas Magento.


ini tidak membahas Created_at dan tidak berfungsi untuk 2.1.9 - setidaknya untuk saya
dawhoo

Bisakah Anda menguraikan bagaimana sekitarSetCollection bekerja?
TheKitMurkit

variabel $ koleksi tidak terdefinisi,
jafar pinjar

4

Jika Anda ingin menggunakan atribut Create At saja , Anda dapat mengaktifkan atribut ini di panel admin dalam opsi penyortiran.

Contoh:

<?php

namespace Vendor\Module\Setup;

use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Setup\ModuleContextInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\UpgradeDataInterface;

class UpgradeData implements UpgradeDataInterface
{
    protected $eavSetupFactory;

    /**
     * UpgradeData constructor.
     *
     * @param EavSetupFactory $eavSetupFactory
     */
    public function __construct(
        EavSetupFactory $eavSetupFactory
    ) {
        $this->eavSetupFactory = $eavSetupFactory;
    }

    /**
     * @param ModuleDataSetupInterface $setup
     * @param ModuleContextInterface $context
     */
    public function upgrade(
        ModuleDataSetupInterface $setup,
        ModuleContextInterface $context
    ) {
        /** @var EavSetup $eavSetup */
        $eavSetup = $this->eavSetupFactory->create(['setup' => $setup]);

        if (version_compare($context->getVersion(), '2.1.1', '<')) {
            try {
                $entityType = $eavSetup->getEntityTypeId('catalog_product');
                $label = 'Created At';
                $eavSetup->updateAttribute($entityType, 'created_at', 'frontend_label', $label, null);
                $eavSetup->updateAttribute($entityType, 'created_at', 'used_for_sort_by', 1, null);
            } catch (LocalizedException $e) {
            }
        }
    }
}

Kode ini dari Setup / UpgradeData.php , tetapi akan lebih baik menggunakan InstallData.php sebagai gantinya.


Di mana kode ini ditambahkan dalam sistem file?
YorkieMagento

1
Mengapa membuat modul khusus untuk mengubah bidang db? saya pikir itu bukan cara terbaik.
LucScu

2

Langkah 1 : Pertama, Anda harus membuat registrasi.php

Nama penjual: Arun

Nama modul: NewSorting

Vendor / Modulename / registration.php

<?php \Magento\Framework\Component\ComponentRegistrar::register(
\Magento\Framework\Component\ComponentRegistrar::MODULE, 'Arun_NewSorting',
__DIR__
);?>

Langkah 2 : Anda membuat module.xml

Vendor / Modulename / etc / module.xml

<?xml version="1.0"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
        xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd">
    <module name="Arun_NewSorting" setup_version="0.0.1">
        <sequence>
            <module name="Magento_Catalog"/>
        </sequence>
    </module>
</config>

Langkah 3 : Anda membuat plugin

Vendor / Modulename / 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">
    <type name="Magento\Catalog\Model\Config">
        <plugin name="Arun_NewSorting::addCustomOptions" type="Arun\NewSorting\Plugin\Model\Config" />
    </type>
    <type name="Magento\Catalog\Block\Product\ProductList\Toolbar">
        <plugin name="Arun_NewSorting::addPriceDecendingFilterInToolbar" type="Arun\NewSorting\Plugin\Product\ProductList\Toolbar" />
    </type>
</config>

Langkah 4 : lalu buat config.php

Vendor / Modulename / Plugin / Model / Config.php

<?php
namespace Arun\NewSorting\Plugin\Model;

use Magento\Store\Model\StoreManagerInterface;

class Config  {


    protected $_storeManager;

    public function __construct(
        StoreManagerInterface $storeManager
    ) {
        $this->_storeManager = $storeManager;
    }


    public function afterGetAttributeUsedForSortByArray(\Magento\Catalog\Model\Config $catalogConfig, $options)
    {
        $store = $this->_storeManager->getStore();
        $currencySymbol = $store->getCurrentCurrency()->getCurrencySymbol();

        // Remove specific default sorting options
        $default_options = [];
        $default_options['name'] = $options['name'];

        unset($options['position']);
        unset($options['name']);
        unset($options['price']);

        //Changing label
        $customOption['position'] = __( 'Relevance' );

        //New sorting options
        $customOption['created_at'] = __( ' New' );


        $customOption['name'] = $default_options['name'];

        //Merge default sorting options with custom options
        $options = array_merge($customOption, $options);

        return $options;
    }
}

Langkah 5 : Ganti Toolbar.php ***

Vendor / Modulename / Plugin / Produk / ProductList / Toolbar.php

<?php
namespace Arun\NewSorting\Plugin\Product\ProductList;

class Toolbar
{

    public function aroundSetCollection(
        \Magento\Catalog\Block\Product\ProductList\Toolbar $subject,
        \Closure $proceed,
        $collection
    ) {
        $currentOrder = $subject->getCurrentOrder();
        $result = $proceed($collection);

        if ($currentOrder) {
            if ($currentOrder == 'created_at') {
                $subject->getCollection()->setOrder('created_at', 'desc');
            } 
        }

        return $result;
    }
}

ini bekerja dengan sempurna


Adakah perintah yang harus dijalankan di CLI setelah memperbarui file-file ini?
YorkieMagento

Perlu dijalankan mengikuti peningkatan pengaturan CLI, penyebaran konten statis, pembersihan cache,
pengindeksan ulang

Terima kasih MSA tetapi ketika saya menjalankan perintah upgrade dikatakan 'tidak ada pembaruan'. Menggunakan 2.2.5. Menyalin semua hal di atas ... tetapi bertanya-tanya apa yang ada dalam file Registration.php yang Anda sebutkan dan di mana menemukannya?
YorkieMagento

Saya memperbarui path file file Registration.php: Vendor / Modulename / registration.php
Arunprabakaran M

Modul yang ditambahkan persis seperti di atas dan opsi 'baru' muncul di ujung depan. Tampaknya telah menggantikan opsi 'posisi' yang diharapkan? Saya tidak dapat melihat opsi dalam katalog di panel admin, karena saya ingin membuat opsi default ini ... Terima kasih.
YorkieMagento

1

Caranya tidak perlu menulis kode

  1. Temukan created_atatribut produk dalam tabel DB eav_attribute, setel kolomnya frontend_labelke Created At(standarnya adalah nol).

  2. Temukan created_atatribut produk dalam tabel DB catalog_eav_attribute, setel kolomnya used_for_sort_byke 1(standarnya adalah 0).

  3. Bersihkan cache situs dan berfungsi.

Contoh: ubah tabel dengan mysql

# Get the attribute_id of 'created_at'
select attribute_id from eav_attribute where attribute_code = 'created_at' and entity_type_id=4;

# Set frontend_label
update eav_attribute set frontend_label = 'Created At' where attribute_id=112;

# Set used_for_sort_by
update catalog_eav_attribute set used_for_sort_by = 1 where attribute_id=112;

Saya tidak akan secara langsung mengubah nilai-nilai db, terutama jika itu adalah data inti.
LucScu

@LucScu Ini hanyalah cara lain yang lebih mudah. Itu mengubah dua bidang DB yang tidak masalah. Anda bisa menggunakan kode untuk mengabaikan fungsi juga, tetapi fungsi yang dicakup akan diubah dalam peningkatan versi, dan Anda harus memperbarui kode khusus Anda. Kedua metode memiliki kelebihan dan kekurangan. Gunakan kode kustom untuk fungsi sederhana sedikit berlebihan.
Key Shang

@ SagarParikhSGR Saya menggunakannya dan berfungsi. Perhatikan penggunaan yang benar attribute_id.
Key Shang

@KeyShang my bad, ini bekerja dengan sempurna, terangkat :)
Sagar Parikh SGR
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.