以下の赤枠にあるようなカタログページのソート機能を、好きな項目でソートできるエクステンションを作成します。

今回は、新着順・値段昇順・値段降順の3つでソートできるようにします。

全体的なイメージ

  • エクステンションを作る準備
  • Pluginを作成
  • di.xmlを作成
  • 和訳ファイルを作成

エクステンションを作る準備

Magento2でエクステンションを作る方法(1)を参考にして、registration.phpとmodule.xmlの2つを作成してください。

Pluginを作成

メソッドを加えることで、このエクステンションは作成できそうです。しかし、coreファイルをいじるのはご法度なので、Pluginを使います。(Pluginのイメージ:magentoのモジュールを拡張したいときに使う機能)

Veriteworks/SortOrder/Plugin/Catalog/Model/Config.php

  • \Magento\Catalog\Model\Config.phpにあるgetAttributeUsedForSortByArrayメソッドを拡張
  • メソッドを拡張するには、拡張したいメソッドの頭にbefore, after, aroundを付け加えて定義することで可能
  • before: 拡張したいメソッドの前に呼び出される
  • after: 拡張したいメソッドの後に呼び出される
  • around: 拡張したいメソッドの前と後に呼び出される
  • 今回はaroundを使用
  • 元々のソート候補にある項目をresetし、新たな項目を追加する
<?php
namespace Veriteworks\SortOrder\Plugin\Catalog\Model;
use Magento\Store\Model\StoreManagerInterface;

/**
 * Class Config
 * @package Veriteworks\SortOrder\Plugin\Catalog\Model
 */
class Config {

    /**
     * Adding custom options and changing labels
     *
     * @param \Magento\Catalog\Model\Config $catalogConfig
     * @param [] $options
     * @return []
     */
    public function afterGetAttributeUsedForSortByArray(\Magento\Catalog\Model\Config $catalogConfig, $options)
    {
        //Remove specific default sorting options
        unset($options['position']);
        unset($options['name']);
        unset($options['price']);
        unset($options['size']);
        unset($options['color']);
        unset($options['color']);

        //New sorting options
        $customOption['created_at'] = __('New to Old');
        $customOption['low_to_high'] = __('Low to High');
        $customOption['high_to_low'] = __('High to Low');

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

        return $options;
    }
}

Veriteworks/SortOrder/Veriteworks/SortOrder/Plugin/Catalog/Block/Product/ProductList/Toolbar.php

  • \Magento\Catalog\Block\Product\ProductList\Toolbar にあるsetCollectionメソッドを拡張
  • 先ほど追加した項目をデータベースにある商品情報と紐づける(created_at, priceなど)
<?php
/**
 * Created by PhpStorm.
 * User: tsuchiya
 * Date: 2018/01/30
 * Time: 9:41
 */
namespace Veriteworks\SortOrder\Plugin\Catalog\Block\Product\ProductList;

/**
 * Class Toolbar
 * @package Veriteworks\SortOrder\Plugin\Catalog\Block\Product\ProductList
 */
class Toolbar extends \Magento\Catalog\Block\Product\ProductList\Toolbar
{

    /**
     * @param \Magento\Catalog\Block\Product\ProductList\Toolbar $subject
     * @param \Closure $proceed
     * @param $collection
     * @return mixed
     */
    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');
            } elseif ($currentOrder == 'high_to_low') {
                $subject->getCollection()->setOrder('price', 'desc');
            } elseif ($currentOrder == 'low_to_high') {
                $subject->getCollection()->setOrder('price', 'asc');
            }
        }

        return $result;
    }
}

エクステンションを作る準備、Pluginを作成まで終わりました。
次回は、di.xmlを作成です。