Magento 2 Cách thêm sắp xếp tùy chỉnh theo tùy chọn


21

Tôi cần thêm một bộ lọc bổ sung dựa trên created_atthuộc tính để sắp xếp danh sách sản phẩm theo sản phẩm mới nhất. Tôi đã cố gắng để tìm nó bằng cách sử dụng tập tin dưới đây

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

nhưng làm thế nào có thể thêm id thực thể của chúng tôi vào getAvailableOrders()?

Câu trả lời:


22

Nếu bạn muốn sử dụng một thuộc tính như thế created_atkhông có trong admin-> store -> (thuộc tính) sản phẩm, vì các thuộc tính được xác định trong quản trị viên có cài đặt Sorting in Product Listing = Yes/No, bạn phải làm việc với hai tệp này:

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

Trong Toolbar.phpbạn có thể thấy

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

nó gọi getAttributeUsedForSortByArray()từ Config.phpđó trả về mảng các thuộc tính có sẵn để sắp xếp bộ sưu tập danh sách.

Bây giờ, bạn phải thêm created_atthuộc tính của bạn ở đây. Làm sao? Tôi đã làm nó với một plugin

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

Bạn đã chèn created_atcác thuộc tính có sẵn để sắp xếp, bây giờ bạn chỉ phải xây dựng bộ sưu tập tùy chỉnh của mình để sử dụng nó. Ở đây tôi chọn ghi đè \vendor\magento\module-catalog\Block\Product\ProductList\Toolbar.php bằng của tôi Toolbar.phpvà ghi đèsetCollection()

/**
 * 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;        
}

Đó là tất cả, đối với tôi làm việc như một nét duyên dáng.


Nếu bất cứ ai muốn mặc định tăng dần, sau đó thay đổi } elseif ( $this->getCurrentDirection() == 'asc' ) {thành } else {.
thdoan

2
Ngoài ra, nếu bạn không muốn sử dụng plugin, bạn cũng có thể sử dụng chức năng công cộng tích hợp $block->addOrderToAvailableOrders('created_at', 'New')trong mẫu sắp xếp của mình.
thdoan

Bạn có thể có giải pháp để sắp xếp giá sản phẩm tùy chỉnh? @Luca
Dhaduk Mitesh

@DhadukMitesh chắc chắn, bạn chỉ có thể sử dụng mã ở trên và thay đổi mã thuộc tính created_atbằng mã thuộc tính giá tùy chỉnh của bạn
LucScu

Tôi không có thuộc tính giá tùy chỉnh. Tôi sử dụng sắp xếp giá mặc định theo. Tôi chỉ thay đổi trong tập tin cốt lõi, nơi sắp xếp giá. và tôi muốn đặt giá tùy chỉnh cho một bộ sưu tập. nhưng tôi không thể đặt giá tùy chỉnh trong bộ sưu tập.
Dhaduk Mitesh

18

Chúng ta có thể đạt được nó bằng cách sử dụng Plugin. Vui lòng tạo các tệp sau trong mô-đun của bạn.

ứng dụng / mã / Gói / 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>

ứng dụng / mã / Gói / 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;
}
}

ứng dụng / mã / Gói / CustomToolbar / Plugin / Sản phẩm / ProductList / Thanh công cụ.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;
    }
}

Điều này hoạt động tốt với tôi mà không cần viết lại bất kỳ lớp Magento nào.


đây không phải là địa chỉ created_at và không hoạt động cho 2.1.9 - đối với tôi ít nhất
dawhoo

Bạn có thể vui lòng giải thích về cách thức hoạt động của xung quanh SetCollection không?
TheKitMurkit

biến không xác định $ bộ sưu tập,
jafar pinjar

4

Nếu bạn muốn sử dụng chỉ thuộc tính Tạo , bạn có thể kích hoạt thuộc tính này trong bảng quản trị trong các tùy chọn sắp xếp.

Thí dụ:

<?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) {
            }
        }
    }
}

Mã này từ Setup / Nâng cấpData.php , nhưng sẽ tốt hơn để sử dụng InstallData.php thay thế.


Mã này được thêm vào ở đâu trong hệ thống tập tin?
YorkieMagento

1
Tại sao tạo một mô-đun tùy chỉnh để thay đổi trường db? Tôi không nghĩ là cách tốt nhất.
LucScu

2

Bước 1 : Đầu tiên bạn nên tạo đăng ký.php

Tên nhà cung cấp: Arun

Tên mô-đun: NewSorting

Nhà cung cấp / Modulename / register.php

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

Bước 2 : Bạn tạo module.xml

Nhà cung cấp / 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>

Bước 3 : Bạn tạo plugin

Nhà cung cấp / 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>

Bước 4 : sau đó tạo config.php

Nhà cung cấp / 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;
    }
}

Bước 5 : Ghi đè Thanh công cụ.php ***

Nhà cung cấp / Modulename / Plugin / Product / ProductList / Thanh công cụ.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;
    }
}

nó hoạt động hoàn hảo


Có lệnh nào được chạy trong CLI sau khi cập nhật các tệp này không?
YorkieMagento

Cần chạy sau nâng cấp thiết lập CLI, triển khai nội dung tĩnh, xóa bộ nhớ cache, reindex
Arunprabakaran M

Cảm ơn MSA nhưng khi tôi chạy lệnh nâng cấp thì nó báo 'không có gì để cập nhật'. Sử dụng 2.2.5. Sao chép tất cả những điều trên ... nhưng tự hỏi có gì trong tập tin Registration.php mà bạn đề cập và vị trí của nó ở đâu?
YorkieMagento

Tôi đã cập nhật đường dẫn nội dung tệp Đăng ký.php: Nhà cung cấp / Modulename / đăng
ký.php

Đã thêm mô-đun chính xác như trên và tùy chọn 'mới' hiển thị ở mặt trước. Nó dường như đã thay thế tùy chọn 'vị trí' được mong đợi? Tôi không thể thấy tùy chọn trong danh mục trong bảng quản trị, vì tôi muốn tạo tùy chọn mặc định này ... Cảm ơn bạn.
YorkieMagento

0

Cách không cần viết mã

  1. Tìm created_atthuộc tính sản phẩm trong bảng DB eav_attribute, đặt cột của nó frontend_labelthành Created At(mặc định là null).

  2. Tìm created_atthuộc tính sản phẩm trong bảng DB catalog_eav_attribute, đặt cột của nó used_for_sort_bythành 1(mặc định là 0).

  3. Làm sạch bộ đệm trang web và nó đang hoạt động.

Ví dụ: thay đổi bảng bằng 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;

Tôi sẽ không trực tiếp thay đổi các giá trị db, đặc biệt nếu đó là dữ liệu cốt lõi.
LucScu

@LucScu Nó chỉ là một cách khác dễ dàng hơn. Nó đã thay đổi hai trường DB không thành vấn đề. Bạn cũng có thể sử dụng mã để ghi đè chức năng, nhưng chức năng được bảo hiểm sẽ được thay đổi trong nâng cấp phiên bản và bạn phải cập nhật mã tùy chỉnh của mình. Cả hai phương pháp đều có ưu điểm và nhược điểm. Sử dụng mã tùy chỉnh cho một chức năng đơn giản là một chút quá mức cần thiết.
Khóa Shang
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.