마 젠토 2 옵션으로 커스텀 정렬을 추가하는 방법


21

created_at최신 제품별로 제품 목록을 정렬하기위한 속성을 기반으로 추가 필터를 추가해야합니다 . 아래 파일을 사용하여 파악하려고했습니다.

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

그러나 엔티티 ID를 어떻게 추가 할 수 getAvailableOrders()있습니까?

답변:


22

created_atadmin에 정의 된 속성에는 설정이 있으므로 admin-> stores-> (attribute) 제품에없는 것과 같은 속성을 사용하려면 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

18

플러그인을 사용하여 달성 할 수 있습니다. 모듈에서 다음 파일을 작성하십시오.

앱 / 코드 / 패키지 /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>

앱 / 코드 / 패키지 /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;
}
}

앱 / 코드 / 패키지 /CustomToolbar/Plugin/Product/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 클래스를 다시 쓰지 않고 나에게 잘 작동합니다.


이것은 created_at를 다루지 않고 2.1.9에서 작동하지 않습니다-적어도
— dawhoo

aroundSetCollection 작동 방식에 대해 자세히 설명해 주시겠습니까?
— TheKitMurkit

정의되지 않은 변수 $ collection
— jafar pinjar 8:27에

4

Create At 속성 만 사용하려는 경우 정렬 옵션의 관리자 패널에서이 속성을 활성화 할 수 있습니다.

예:

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

이 코드는 Setup / UpgradeData.php의 코드 이지만 InstallData.php 를 사용하는 것이 좋습니다.


이 코드는 파일 시스템에서 어디에 추가됩니까?
— YorkieMagento

1
DB 필드를 변경하기 위해 사용자 정의 모듈을 작성하는 이유는 무엇입니까? 나는 최선의 방법이라고 생각하지 않습니다.
— LucScu

2

1 단계 : 먼저 registration.php를 만들어야합니다

공급 업체 이름 : Arun

모듈 이름 : NewSorting

공급 업체 / 모듈 이름 /registration.php

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

2 단계 : module.xml을 작성합니다

공급 업체 / 모듈 이름 /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 단계 : 플러그인 생성

공급 업체 / 모듈 이름 /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 생성

공급 업체 / 모듈 이름 / 플러그인 / 모델 /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 *** 재정의

공급 업체 / 모듈 명 / 플러그인 / 제품 / 제품 목록 /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에게 감사하지만 업그레이드 명령을 실행하면 'Nothing to update'가 표시됩니다. 사용 2.2.5. 위의 모든 내용을 복사했지만 ... Registration.php 파일에 무엇이 있고 어디에서 찾을 수 있는지 궁금하십니까?
— YorkieMagento

나는 Registration.php 파일 내용 경로를 업데이트 : 공급 업체 / MODULENAME / registration.php
— Arunprabakaran M

위와 같이 정확하게 모듈을 추가하면 프론트 엔드에 'new'옵션이 표시됩니다. '위치'옵션을 대체 한 것으로 보입니다. 이 기본 옵션을 만들고 싶습니다. 관리자 패널에서 카탈로그에 옵션이 표시되지 않습니다 ... 감사합니다.
— YorkieMagento

0

방법은 코드를 작성할 필요가 없습니다

  1. created_atDB table에서 제품 속성을 찾아 eav_attribute열 frontend_label을 Created At(기본값은 null)로 설정하십시오.

  2. created_atDB 테이블에서 제품 속성을 찾아 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 또 다른 쉬운 방법입니다. 중요하지 않은 두 개의 DB 필드가 변경되었습니다. 코드를 사용하여 기능을 재정의 할 수도 있지만 버전 업그레이드시 해당 기능이 변경되므로 사용자 지정 코드를 업데이트해야합니다. 두 방법 모두 장단점이 있습니다. 간단한 기능을 위해 사용자 정의 코드를 사용하는 것은 약간의 과잉입니다.
— Key Shang
당사 사이트를 사용함과 동시에 당사의 쿠키 정책과 개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.