ec-cube 4.0.3 よく一緒に購入されている商品(レコメンド)を表示させる

投稿者: | 2020-05-16
Table of Content

ショッピングサイトに当たり前のようにある、商品詳細ページに「よく一緒に購入されている商品」を表示させる機能がec-cube4にはないので、簡単なレコメンドを表示する関数を作成した(MySQLを使用)。

手順

  1. Twig Extension を作成する
  2. 「よく一緒に購入されている商品」のブロックを作成する
  3. 商品詳細用レイアウトを作成して、2で作成したブロックを設定する

Twig Extension を作成する

ファイルを新規作成
app/Customize/Twig/Extension/FsBuyTogether.php

過去120日間の購入履歴を参照して、商品を6つ取得する。

<?php

namespace Customize\Twig\Extension;

use Doctrine\ORM\EntityManagerInterface;
use Eccube\Entity\Master\ProductStatus;
use Eccube\Repository\ProductRepository;
use Twig\Extension\AbstractExtension;
use Twig\TwigFunction;

class FsBuyTogether extends AbstractExtension
{
    /** @var EntityManagerInterface */
    private $entityManager;

    /**
     * @var ProductRepository
     */
    private $productRepository;

    /**
     * FsBuyTogether constructor.
     *
     * @param EntityManagerInterface $entityManager
     * @param ProductRepository $productRepository
     */
    public function __construct(
        EntityManagerInterface $entityManager,
        ProductRepository $productRepository
    ) {
        $this->entityManager = $entityManager;
        $this->productRepository = $productRepository;
    }

    /**
     * Returns a list of functions to add to the existing list.
     *
     * @return array An array of functions
     */
    public function getFunctions()
    {
        return [
            new TwigFunction('FsBuyTogether', [$this, 'getFsBuyTogether'])
        ];
    }

    /**
     * Name of this extension
     *
     * @return string
     */
    public function getName()
    {
        return 'FsBuyTogether';
    }

    /**
     * よく一緒に購入されている商品
     *
     * @param int $productId
     *
     * @return array
     */
    public function getFsBuyTogether($productId)
    {
        $days = 120;    // 過去120日間の購入履歴を参照する
        $searchDate = date('Y-m-d 00:00:00', strtotime( date('Ymd') . '-'. $days . ' day' ) );

        $CheckProducts = [];
        if (0 == $productId) { return $CheckProducts; }

        try {
            $sql = 'select 
        t3.id, count(t3.id) as cnt
    from
        dtb_product t3
        left join dtb_order_item t4 
            on t3.id = t4.product_id and t3.product_status_id=1
    where
        t3.id <> :id 
        and order_id in (
            select
                t1.id
            from
                dtb_order t1 left join dtb_order_item t2 on t1.id = t2.order_id
            where
                t1.create_date >= :create_date and t2.product_id = :id 
            group by
                t1.id
        )
    group by
        t3.id
    order by
        cnt desc limit 6';

            $stmt = $this->entityManager->getConnection()->prepare($sql);
            $stmt->execute(['id' => $productId, 'create_date' => $searchDate]);
            $result = $stmt->fetchAll();

            foreach ($result as $id) {
                $Product = $this->productRepository->find($id['id']);
                if(!is_null($Product) && $Product->getStatus()->getId() === ProductStatus::DISPLAY_SHOW) {
                    $CheckProducts[] = $Product;
                }
            }

            return $CheckProducts;
        } catch (\Exception $e) {
            $CheckProducts = [];
        }

        return $CheckProducts;
    }
}

ブロックを作成する

ファイルを新規作成
app/template/default/Block/buy_together.twig

管理画面の「コンテンツ管理」->「ブロック管理」を開いて新規作成

ec-cube 4 レコメンド ブロック作成

{#
よく一緒に購入されている商品
#}
{% if app.request.get('_route') == 'product_detail' %}
    {% set FsBuyTogetherProducts = FsBuyTogether( Product.id ) %}

    {% if FsBuyTogetherProducts|length > 0 %}
<div class="ec-role">
    <div class="row">
        <h2 class="title mgL">よく一緒に購入されている商品</h2>

        {% set i = 1 %}
        {% for Product in FsBuyTogetherProducts %}
        <div class="col-xs-6 col-md-2">
            <div class="thumbnail">
                <a href="{{ url('product_detail', {'id' : Product.id}) }}" class="item_photo">
                <img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}"></a>
                <div class="caption">
                    <h3>{{ Product.name }}</h3>
                    <p><span class="ec-price__price">{{ Product.getPrice02IncTaxMin|price }}</span>
                        <span class="ec-price__tax">{{ 'common.tax_include'|trans }}</span></p>
                </div>
            </div>
        </div>
            {% if ((i % 2 == 0) and (0 < i)) %}
                <div class="clearfix visible-xs"></div>
            {% endif %}
            {% set i = i + 1 %}

        {% endfor %}

    </div>
</div>
    {% endif %}

{% endif %}

作成したブロックを表示させるページは商品詳細ページだけにしたいので、商品詳細用のレイアウトを作成する(上記のブロック内で商品詳細ページかどうかの判定を入れているので、「下層ページレイアウト」のままでもいい)。

管理画面の「コンテンツ管理」->「レイアウト管理」を開いて新規作成。

ec-cube 4 レコメンド

作成した商品詳細用レイアウトに上記で作成した「よく一緒に購入されている商品」ブロックをドラッグ&ドロップして配置。
次に「ページ管理」で、商品詳細ページは商品詳細用レイアウトを使うように設定する。

ec-cube 4 レコメンド

コメントを残す

メールアドレスが公開されることはありません。

CAPTCHA