EC-CUBE4:商品の並び順をカスタマイズ
最終更新日:2020/04/13
在庫のない商品の並び順を後ろにまわす
このカスタマイズは2系、3系の時もやっていたので、4系でもやってみることにしました。
src/Eccube/Repository/ProductRepository.phpの167行目付近
// Order By
// 価格低い順
$config = $this->eccubeConfig;
if (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_lower']) {
//@see http://doctrine-orm.readthedocs.org/en/latest/reference/dql-doctrine-query-language.html
$qb->innerJoin('p.ProductClasses', 'pc'); // visible,stock,stock_unlimitedを参照するためjoin
$qb->andWhere('pc.visible = true'); // 非表示設定されていないもののみ対象
$qb->addSelect('MIN(pc.price02) as HIDDEN price02_min','(case when SUM(pc.stock) > 0 then 1 else 0 end + case when SUM(pc.stock_unlimited) > 0 then 1 else 0 end) as HIDDEN stock_boolean'); // stock,stock_unlimitedがひとつでもあれば1に
$qb->groupBy('p.id');
$qb->orderBy('stock_boolean', 'DESC');// 在庫数ではない単純な在庫有無でのソート
$qb->addorderBy('price02_min', 'ASC');// 価格でのソート
$qb->addOrderBy('p.id', 'DESC');// idでのソートソート
// 価格高い順
} elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_price_higher']) {
$qb->innerJoin('p.ProductClasses', 'pc');
$qb->andWhere('pc.visible = true');
$qb->addSelect('MAX(pc.price02) as HIDDEN price02_max','(case when SUM(pc.stock) > 0 then 1 else 0 end + case when SUM(pc.stock_unlimited) > 0 then 1 else 0 end) as HIDDEN stock_boolean');
$qb->groupBy('p.id');
$qb->orderBy('stock_boolean', 'DESC');
$qb->addorderBy('price02_max', 'DESC');
$qb->addOrderBy('p.id', 'DESC');
// 新着在庫順
} elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == 5) {
$qb->innerJoin('p.ProductClasses', 'pc');
$qb->andWhere('pc.visible = true');
$qb->addSelect('(case when SUM(pc.stock) > 0 then 1 else 0 end + case when SUM(pc.stock_unlimited) > 0 then 1 else 0 end) as HIDDEN stock_boolean');
$qb->groupBy('p.id');
$qb->orderBy('stock_boolean', 'DESC');
$qb->addOrderBy('p.create_date', 'DESC');// 登録日でのソート
$qb->addOrderBy('p.id', 'DESC');
// 新着順
} elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == $config['eccube_product_order_newer']) {
// 在庫切れ商品非表示の設定が有効時対応
// @see https://github.com/EC-CUBE/ec-cube/issues/1998
if ($this->getEntityManager()->getFilters()->isEnabled('option_nostock_hidden') == true) {
$qb->innerJoin('p.ProductClasses', 'pc');
$qb->andWhere('pc.visible = true');
}
$qb->OrderBy('p.create_date', 'DESC');
$qb->addOrderBy('p.id', 'DESC');
// 名前順
} elseif (!empty($searchData['orderby']) && $searchData['orderby']->getId() == 4) {
// 在庫切れ商品非表示の設定が有効時対応
// @see https://github.com/EC-CUBE/ec-cube/issues/1998
if ($this->getEntityManager()->getFilters()->isEnabled('option_nostock_hidden') == true) {
$qb->innerJoin('p.ProductClasses', 'pc');
$qb->andWhere('pc.visible = true');
}
$qb->orderBy('p.name', 'ASC');
$qb->addOrderBy('p.id', 'DESC');
} else {
以前は、価格が低い順、高い順、新着在庫順のaddSelectに'MAX(pc.stock) as HIDDEN stock_max'を加え、
$qb->orderBy('stock_max', 'DESC');で在庫のない商品が後ろに行くようにしていましたが、
これだと在庫のあるものも在庫数順優位で表示されてしまっていました。
ですが、これについて、
stock_booleanを使うといい、というあけびさんのアドバイスのおかげで、在庫数に関わらず指定した表示順で表示されるようになりました。
あけびさん、いつも貴重なアドバイスをありがとうございます❤
(2020.4.13: これまでの記事では、新着在庫順についてのみstock_booleanを用いていましたが、価格順についてもstock_booleanを使う記述に直し、全体的にコードを入れ替えました)
上のコードに、カスタマイズしていないデフォルトの「新着順」と、在庫のない商品を後ろにまわすようカスタマイズした「新着在庫順」の2つがあるのは、
トップページに新着商品を表示するカスタマイズで、設定したTwigExtentionが、商品情報の取得にこのProductRepository.php中の新着順($config['eccube_product_order_newer'])を定義しているためです。
私はトップページでは在庫の有無に関わらず商品登録順で商品を掲載したかったので、「新着順」はそのまま残し
商品一覧ページでは「新着在庫順」をデフォルトで表示させるようにしました。
商品一覧ページでどの並び順をデフォルトで表示させるかは、管理画面の「設定」「マスターデータ管理」の「mtb_product_list_order_by」で設定できます。