마 젠토 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_attributefrontend_labelCreated At(기본값은 null)로 설정하십시오.

  2. created_atDB 테이블에서 제품 속성을 찾아 catalog_eav_attributeused_for_sort_by1(기본값은 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.