EC-CUBE公式から「商品レビュー管理プラグイン」というプラグインが出ています。
こちらは名前の通り商品にレビューを投稿できるようになるというプラグインになります。
ECサイト実装時にはこのプラグインにはお世話になっているのですが、商品詳細ページにレビューが表示されるのみで商品一覧には表示されません。
この記事では、Amazonのように商品一覧にも星を表示する方法をご紹介します。
手順1.星表示用のブロックを作成
星を出力する場所はおすすめ商品、最近チェックした商品というように複数箇所で表示できるように、レビュー用のブロックを作成してご使い回せるようにブロックで管理をしたいと思います。
app/tempalte/default/Blockにreview.twigを作成します。中身は下記となります。
{# 星テキスト生成用マクロ #}
{% macro stars(positive, negative) %}
{% set positive_stars = ["", "★", "★★", "★★★", "★★★★", "★★★★★"] %}
{% set negative_stars = ["", "☆", "☆☆", "☆☆☆", "☆☆☆☆", "☆☆☆☆☆"] %}
{{ positive_stars[positive] }}{{ negative_stars[negative] }}
{% endmacro %}
{# 該当商品の商品レビュープラグインの値を取得 #}
{% set ProductReview = repository('Plugin\\ProductReview42\\Entity\\ProductReview').findBy({ Product: pid }) %}
{# レビューがあるときだけループをまわす/ない場合は空の星を表示 #}
{% if ProductReview is defined and ProductReview is not empty %}
{# レビューの平均を計算 #}
{% set totalRecommendLevel = 0 %}
{% set reviewCount = 0 %}
{% for review in ProductReview %}
{% set totalRecommendLevel = totalRecommendLevel + review.recommend_level %}
{% set reviewCount = reviewCount + 1 %}
{% endfor %}
{% set ProductReviewAvg = totalRecommendLevel / reviewCount %}
{% set positive_avg_star = ProductReviewAvg | round %}
{% set negative_avg_star = 5 - positive_avg_star %}
<div class="review_stars">
<p class="stars">{{ _self.stars(positive_avg_star, negative_avg_star) }}</p>
<p class="count"><a href="{{ url('product_detail', {'id': Product.id}) }}#product_review_area">({{ reviewCount }})</a></p>
</div>
{% else %}
<div class="review_stars">
<p class="stars">☆☆☆☆☆</p>
<p class="count">(0)</p>
</div>
{% endif %}
手順2.表示したい箇所にブロックを読み込む
星を表示したい箇所で上記ブロックを読み込みます。
注意点としては下記の読み込みの記述は{ pid : Product.id }の引数を渡すためにProduct.idの値がとれている箇所に記述する必要があるので、Productをまわしているfor分の中に記載してください。
例えばlist.twigの場合であれば{% for Product in pagination %}の中になります。
個々の商品の値をreview.twig側に渡すために引数に{ pid : Product.id }を記述してください。
{{ include('Block/review.twig', { pid : Product.id }, ignore_missing = true) }}
新しく作成したBlockの場合
新しいBlockだと情報がなにもないので、リポジトリ関数で商品情報を取得します。
※下記は公開されている商品情報を取得してfor文で回しています。for文の中に先程のインクルードを記述します。
{% set Products = repository('Eccube\\Entity\\Product').findBy({ Status: 1 }) %}
{% for Product in Products %}
{{ include('Block/review.twig', { pid : Product.id }, ignore_missing = true) }}
{% endfor %}