【EC-CUBE4.2】直近◯日間の商品ランキングを表示するカスタマイズ方法

この記事は、EC-CUBE Advent Calendar 2023 の9日目の記事です。
通販サイトを運営する上で、人気商品のランキング表示は売上に直結する重要なポイントです。
そこで今回は、EC-CUBE4.2系で簡単に実装できる、直近◯日間の商品ランキング表示機能のカスタマイズ方法を紹介します。
目次
1. カスタマイズの概要とステップ
このカスタマイズは、プログラミングの基本知識を持つ方なら比較的かんたんに実装できます。
以下の3つのステップに分けて、機能を実装していきます。
- リポジトリのカスタマイズ:売上高の高い商品を取得するためのカスタマイズされたリポジトリを作成します。
- イベントリスナーの設定:商品データをランキングブロックに渡すためのイベントリスナーを設定します。
- ブロック・レイアウト設定:ランキング表示用のブロックを作成して、サイトのレイアウトに組み込みます。
2. リポジトリの作成
まずは、EC-CUBEのデータベースから売上高の高い商品を取得するためのリポジトリの作成です。
Repositoryでは、商品(Product)単位ではなく、商品規格(ProductClass)毎の売上を取得しており、次のEventListenerの設定で、商品(Product)単位に加工します。
getProductsRanking() の引数を変更することで、何日間の売上を集計するかを変更できます。
※デフォルトでは7日にしています。
以下のPHPファイルを「/app/Customize/Repository/」のディレクトリに保存してください。
https://github.com/cajiya/sample_code/blob/main/2023/1207/RankingRepository.php
以下は主要部分のコードの抜粋です。
/**
* 売上ランキングを取得する
*
* @param int $recentLimit 取得する最新のOrderItemの数
* @return array 商品の売上ランキングデータ
*/
public function getProductsRanking( $recentLimit = 7)
{
// ProductClass毎の売上高を取得するためのクエリ
$qb = $this->createQueryBuilder('oi')
->select(' IDENTITY(oi.ProductClass) as product_class_id, IDENTITY(oi.Product) as product_id , SUM(oi.quantity) * (oi.price + oi.tax) as total_price')
->join('oi.OrderItemType', 'oit')
->join('oi.Order', 'o')
->where('oit.id = :orderItemTypeProduct')
->andWhere('o.order_date > :recent_date')
->groupBy('oi.ProductClass')
->orderBy('total_price', 'DESC')
->setParameter('orderItemTypeProduct', OrderItemType::PRODUCT)
->setParameter('recent_date', new \DateTime("-{$recentLimit} days") );
// クエリの実行と結果の取得
return $qb->getQuery()->getResult();
}
3. イベントリスナーの設定
次は、Repositoryから受け取ったレコードを加工して、ranking.twigブロックにデータを渡すためのEventListenerの設定です。
このイベントリスナーは、ranking.twigが呼び出された際に動作し、ランキング順に並んだProductのリストをテンプレートに渡します。
以下のPHPファイルを「/app/Customize/EventListener/」のディレクトリに保存してください。
https://github.com/cajiya/sample_code/blob/main/2023/1207/RankingRepository.php
以下は主要部分のコードの抜粋です。
/**
* テンプレートイベントのリスナー
* 売上ランキングをテンプレートに渡すための処理
*
* @param TemplateEvent $event テンプレートイベント
*/
public function onRanking(TemplateEvent $event)
{
// 現在のテンプレートのパラメータを取得
$parameters = $event->getParameters();
// 売上ランキングのデータを取得
$ProductClasses = $this->rankingRepository->getProductsRanking();
$event->setParameters($parameters);
$sums = [];
$Products = [];
if (!empty($ProductClasses)) {
foreach ($ProductClasses as $item) {
if (!isset($sums[$item['product_id']])) {
$sums[$item['product_id']] = 0;
}
$sums[$item['product_id']] += $item['total_price'];
}
// 合計をtotal_priceで並び替え
arsort($sums);
// 結果を表示(必要に応じて)
foreach ($sums as $productId => $totalPrice) {
// 商品IDに基づいて商品情報を取得
$Products[] = current($this->productRepository->findBy(['id' => $productId]));
}
}
// // テンプレートにランキング商品を渡す
$parameters['rankingProducts'] = $Products;
$event->setParameters($parameters);
}
4. ブロック・レイアウト設定
ここからは、EC-CUBEの管理画面からの操作になります。
EC-CUBEの管理画面にログインし、「コンテンツ管理>ブロック管理」に移動してください。ここで、「新規作成」ボタンをクリックし、新しいブロックを作成します。ブロックの名称は「ranking」とし、ファイル名には必ず「ranking.twig」を指定してください。ファイル名が異なると、ランキング機能は正常に動作しませんので注意が必要です。
ranking.twig ファイルには以下のコードを登録します。このコードは、直近7日間の売上ランキングを表示するためのものです。
<h5>直近7日間の売上ランキング</h5>
{% for index, Product in rankingProducts %}
<p>{{ index + 1 }}位:{{ Product.name }}</p>
{% endfor %}
<hr>
最後に、「コンテンツ管理>レイアウト管理理>トップページ用レイアウト」に移動して、「ランキング」のブロックを好きな場所に設定すると、トップページのお好きな位置に、売上上位の商品データを表示することができます。
5. まとめ
今回の記事では、EC-CUBE4.2系を利用して直近◯日間の商品ランキングを表示するカスタマイズ方法を紹介しました。
ぜひこのカスタマイズを活用してみてください。


