Magento 2 วิธีเพิ่มการจัดเรียงแบบกำหนดเองตามตัวเลือก


22

ฉันต้องเพิ่มตัวกรองเพิ่มเติมตามcreated_atคุณลักษณะสำหรับการเรียงลำดับรายการผลิตภัณฑ์ตามผลิตภัณฑ์ล่าสุด ฉันพยายามคิดโดยใช้ไฟล์ด้านล่าง

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

แต่จะเพิ่มรหัสเอนทิตีของเราได้getAvailableOrders()อย่างไร

คำตอบ:


23

หากคุณต้องการใช้คุณสมบัติเช่นcreated_atนั้นมันไม่ได้อยู่ในผลิตภัณฑ์ admin-> stores -> (แอตทริบิวต์) เนื่องจากแอตทริบิวต์ที่กำหนดในผู้ดูแลระบบมีการตั้งค่าSorting in Product Listing = Yes/Noคุณต้องทำงานกับสองไฟล์เหล่านี้:

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

ในที่Toolbar.phpคุณสามารถดู

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

มันเรียกgetAttributeUsedForSortByArray()จากConfig.phpที่ส่งกลับอาร์เรย์ของคุณลักษณะที่มีอยู่เพื่อเรียงลำดับรายการคอลเลกชัน

ตอนนี้คุณต้องเพิ่มcreated_atคุณสมบัติของคุณที่นี่ อย่างไร? ฉันทำมันด้วยปลั๊กอิน

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

คุณแทรกcreated_atในแอททริบิวที่มีอยู่เพื่อเรียงลำดับตอนนี้คุณมีเพียงเพื่อสร้างคอลเลกชันที่กำหนดเองเพื่อใช้งาน ที่นี่ฉันเลือกที่จะแทนที่ \vendor\magento\module-catalog\Block\Product\ProductList\Toolbar.phpด้วยเหมืองToolbar.phpและแทนที่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;        
}

นั่นคือทั้งหมดสำหรับฉันทำงานเหมือนจับใจ


หากใครต้องการที่จะเริ่มต้นที่จะน้อยไปมากแล้วเปลี่ยนไป} elseif ( $this->getCurrentDirection() == 'asc' ) { } else {
thdoan

2
นอกจากนี้หากคุณไม่ต้องการใช้ปลั๊กอินคุณสามารถใช้ฟังก์ชันสาธารณะ$block->addOrderToAvailableOrders('created_at', 'New')ในตัวในเทมเพลตตัวเรียงลำดับของคุณ
thdoan

คุณมีทางออกสำหรับการเรียงลำดับราคาผลิตภัณฑ์ที่กำหนดเองได้หรือไม่? @Luca
Dhaduk Mitesh

@DhadukMitesh แน่ใจว่าคุณสามารถใช้รหัสด้านบนและเปลี่ยนรหัสแอตทริบิวต์created_atด้วยรหัสแอตทริบิวต์ราคาที่กำหนดเองของคุณ
LucScu

ฉันไม่มีแอตทริบิวต์ราคาที่กำหนดเอง ฉันใช้ราคาเริ่มต้นเรียงตาม ฉันเปลี่ยนเฉพาะไฟล์แกนที่เรียงลำดับราคา และฉันต้องการกำหนดราคาที่กำหนดเองสำหรับคอลเลกชัน แต่ฉันไม่สามารถกำหนดราคาที่กำหนดเองได้ในการรวบรวม
Dhaduk Mitesh

19

เราสามารถทำได้โดยใช้โปรแกรมเสริม กรุณาสร้างไฟล์ต่อไปนี้ในโมดูลของคุณ

app / รหัส / แพ็กเกจ / 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 / รหัส / แพ็กเกจ / CustomToolbar / ปลั๊กอิน / รุ่น / 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 / รหัส / แพ็กเกจ / CustomToolbar / ปลั๊กอิน / สินค้า / 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;
    }
}

นี่ใช้ได้ดีสำหรับฉันโดยไม่ต้องเขียนคลาส Magento ใหม่


นี่ไม่ได้สร้างไว้แล้วและไม่ทำงานกับ 2.1.9 - สำหรับฉันอย่างน้อย
dawhoo

คุณช่วยอธิบายรายละเอียดเกี่ยวกับวิธีการทำงานของ SetSetCollection ได้ไหม?
TheKitMurkit

ตัวแปร $ collection ที่ไม่ได้กำหนด
jafar pinjar

4

หากคุณต้องการใช้เพียงแค่สร้างแอททริบิวต์คุณสามารถเปิดใช้งานแอททริบิวนี้ในแผงควบคุมของผู้ดูแลระบบในการเรียงลำดับตัวเลือก

ตัวอย่าง:

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

รหัสนี้จากการติดตั้ง / UpgradeData.phpแต่จะดีกว่าที่จะใช้InstallData.phpแทน


รหัสนี้เพิ่มที่ไหนในระบบไฟล์?
YorkieMagento

1
เหตุใดจึงสร้างโมดูลที่กำหนดเองเพื่อเปลี่ยนเขตข้อมูล db ฉันไม่คิดว่าเป็นวิธีที่ดีที่สุด
LucScu

2

ขั้นตอนที่ 1 : ขั้นแรกคุณควรสร้าง register.php

ชื่อผู้ขาย: อรุณ

ชื่อโมดูล: NewSorting

ผู้ขาย / modulename / registration.php

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

ขั้นตอนที่ 2 : คุณสร้าง module.xml

ผู้ขาย / 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>

ขั้นตอนที่ 3 : คุณสร้างปลั๊กอิน

ผู้ขาย / 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>

ขั้นตอนที่ 4 : จากนั้นสร้าง config.php

ผู้ขาย / modulename / ปลั๊กอิน / รุ่น / 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;
    }
}

ขั้นตอนที่ 5 : แทนที่ Toolbar.php ***

ผู้ขาย / modulename / ปลั๊กอิน / สินค้า / 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;
    }
}

มันทำงานได้อย่างสมบูรณ์แบบ


มีคำสั่งใดบ้างที่จะทำงานใน CLI หลังจากอัปเดตไฟล์เหล่านี้ได้ไหม
YorkieMagento

จำเป็นต้องเรียกใช้การอัปเดตการตั้งค่า CLI ต่อไปนี้การปรับใช้เนื้อหาแบบคงที่แคชสะอาดการทำดัชนี
Arunprabakaran M

ขอบคุณ MSA แต่เมื่อฉันเรียกใช้คำสั่งอัพเกรดมันบอกว่า 'ไม่มีอะไรให้อัพเดท' ใช้ 2.2.5 คัดลอกข้างต้นทั้งหมด ... แต่สงสัยว่ามีอะไรอยู่ในไฟล์ Registration.php ที่คุณพูดถึงและจะหาได้ที่ไหน
YorkieMagento

ฉันอัปเดตเส้นทางเนื้อหาไฟล์ Registration.php: ผู้ขาย / Modulename / registration.php
อรุณประภาการะรัน M

เพิ่มโมดูลตรงตามด้านบนและตัวเลือก 'ใหม่' จะแสดงที่ส่วนหน้า ดูเหมือนว่าจะแทนที่ตัวเลือก 'ตำแหน่ง' ที่คาดว่าจะเป็นอย่างไร ฉันไม่เห็นตัวเลือกในแคตตาล็อกในแผงการดูแลระบบเนื่องจากฉันต้องการให้ตัวเลือกเริ่มต้นนี้ ... ขอบคุณ
YorkieMagento

1

วิธีไม่จำเป็นต้องเขียนโค้ด

  1. ค้นหาcreated_atแอตทริบิวต์ผลิตภัณฑ์ในตาราง DB eav_attributeตั้งค่าคอลัมน์frontend_labelเป็นCreated At(ค่าเริ่มต้นคือ null)

  2. ค้นหาcreated_atแอตทริบิวต์ผลิตภัณฑ์ในตาราง DB catalog_eav_attributeตั้งค่าคอลัมน์used_for_sort_byเป็น1(ค่าเริ่มต้นคือ 0)

  3. ล้างแคชของไซต์และใช้งานได้

ตัวอย่าง: เปลี่ยนตารางโดย 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;

ฉันจะไม่เปลี่ยนค่า db โดยตรงโดยเฉพาะถ้าเป็นข้อมูลหลัก
LucScu

@LucScu มันเป็นอีกวิธีที่ง่ายกว่า มันเปลี่ยนสองช่องฐานข้อมูลที่ไม่สำคัญ คุณสามารถใช้รหัสเพื่อแทนที่ฟังก์ชั่นได้เช่นกัน แต่ฟังก์ชั่นที่ครอบคลุมจะเปลี่ยนไปในการอัพเกรดเวอร์ชั่นและคุณต้องอัปเดตรหัสที่กำหนดเองของคุณ ทั้งสองวิธีมีข้อดีและข้อเสีย ใช้รหัสที่กำหนดเองสำหรับฟังก์ชั่นที่เรียบง่ายเป็นบิตมากเกินไป
Key Shang

@SagarParikhSGR ฉันใช้มันและมันใช้งานได้ attribute_idให้ความสนใจกับการใช้ที่เหมาะสม
Key Shang

@KeyShang ไม่ดีของฉันมันทำงานได้อย่างสมบูรณ์ upvoted :)
Sagar Parikh SGR
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.