本サイトでは、以下のような特定条件に合った商品のみを表示するページやブロックの作り方を紹介してきました。
ところが、これらのソースコードをそのままに作られたページでは、商品の公開状態(公開、非公開、廃止)に関係なく商品が表示されてしまうという欠点があります。

商品管理で、商品の一つ(サンプル_4)の公開状態を “非公開” にしているが・・・

実際にページを開いてみると、サンプル_4がそのまま表示されている。
そこで本記事では、この部分を改善するために追加してほしいコードを紹介します。
デフォルトで用意されている商品一覧ページでは、公開状態が非公開または廃止になると非表示になるので、こちらは修正しなくてもOKです。
またこの方法を使えば、公開状態に応じて様々な操作を行うことも可能になります。
“非公開” や “廃止” でも商品が表示されてしまう理由
つまり、『商品の公開状態 = “公開”』になってるものを判別する「if文」をTwigテンプレートに追記したり、商品を検索する「findbyメソッド」に検索条件を追記したりすれば解決するはずです。
【1】Twigテンプレートに「if文」を追記する
まず商品の公開状態は、データベースでは『mtb_product_status』テーブルに格納されています。

これによると、公開状態の “公開” は「id = 1」であるため、
「公開状態のid = 1」のときのみ表示というif文を使ったコード(以下)を追記すれば良さそうです。
{% if Product.status.id == 1 %}
~~商品情報~~
{% endif %}
Product
には、Controllerから渡された商品情報が格納されています。
商品の公開状態はProduct.status
で取得でき、Product.status.id
でid情報を取得できます。
idが1の場合にのみ、{% if Product.status.id == 1 %}
と{% endif %}
で囲まれた部分が実行されるようになります。

実際に、前回作成した新着商品一覧のTwigテンプレートを以下の通り修正しました。
{% extends 'default_frame.twig' %}
{% block main %}
<h1>新着商品ページ</h1>
<div class="ec-shelfRole">
<ul class="ec-shelfGrid">
{% for Product in Products %}
{# 公開状態が「公開」の場合のみ商品を表示 #}
{% if Product.status.id == 1 %}
<li class="ec-shelfGrid__item">
<a href="{{ url('product_detail', {'id': Product.id}) }}">
{# 商品画像の表示 #}
<p class="ec-shelfGrid__item-image">
<img src="{{ asset(Product.main_list_image|no_image_product, 'save_image') }}" alt="{{ Product.name }}">
</p>
{# 商品IDの表示 #}
<p>ID: {{ Product.id }}</p>
{# 商品名の表示 #}
<p>{{ Product.name }}</p>
{# 価格の表示 #}
<p class="price02-default">
{% if Product.hasProductClass %}
{% if Product.getPrice02Min == Product.getPrice02Max %}
{{ Product.getPrice02IncTaxMin|price }}
{% else %}
{{ Product.getPrice02IncTaxMin|price }} ~ {{ Product.getPrice02IncTaxMax|price }}
{% endif %}
{% else %}
{{ Product.getPrice02IncTaxMin|price }}
{% endif %}
</p>
</a>
</li>
{% endif %}
{% endfor %}
</ul>
</div>
{% endblock %}

商品管理で、商品の一つ(サンプル_4)の公開状態を “非公開” にすると・・・

無事、サンプル_4が表示されなくなりました!
【2】findByメソッドに条件を追記する
そもそもControllerにて商品を取得するときに、「公開状態のid = 1」を満たす商品のみを取得するという方法もあります。商品を検索・取得するコードを、以下に修正してください。
// 表示ステータスが1の公開商品のみを、IDの大きい順(降順)で取得。
$products = $this->productRepository->findBy(
['Status' => 1], // ステータスが1の商品を取得
['id' => 'DESC'] // IDの降順で並べる
);
findBy()
の第一引数にフィルタリング条件を配列で渡せるため、['Status' => 1]
という条件を加えました。
この方法であれば、公開状態が1の商品のみを検索してTwigに渡せます。(Twig側を変更する必要はありません。)

まとめ
以上、商品の公開ステータスに応じて表示・非表示を切り替える方法を2つ紹介しました。
登録した商品が廃盤になったり、何かしらの事情で一時的に非公開にしておきたい場合、このようなステータスを操作できると便利ですよね。
今回は非表示にする方法のみでしたが、応用すれば商品ページに【完売】【SOLD OUT】のような表示を出すことなどもできます。
ぜひ、いろいろな使い方を試してみてください!
