{#
This file is part of EC-CUBE
Copyright(c) EC-CUBE CO.,LTD. All Rights Reserved.
http://www.ec-cube.co.jp/
For the full copyright and license information, please view the LICENSE
file that was distributed with this source code.
#}
{# ============================================================
カテゴリナビゲーション(SP版)
機能:
- カテゴリ一覧をツリー構造で表示
- 在庫切れカテゴリの表示/非表示切り替え対応
- カウント表示の動的切り替え対応(全商品数/在庫あり商品数)
============================================================ #}
{# データ取得 #}
{% set Categories = repository('Eccube\\Entity\\Category').getList() %}
{% set CategoriesCount = repository('Eccube\\Entity\\Product').findProductsWithCategoriesCount() %}
{% set CategoriesCountInStock = repository('Eccube\\Entity\\Product').findProductsWithCategoriesCountInStock() %}
{% set Makers = repository('Plugin\\Maker42\\Entity\\Maker').findBy({}, {sort_no: 'desc' }, 5) %}
{# ============================================================
マクロ: hasStockInTree
目的: カテゴリまたはその子孫カテゴリに在庫あり商品があるか判定
引数:
- Category: 判定対象のカテゴリエンティティ
- CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
戻り値: 'true' または 'false' (文字列)
ロジック:
1. 該当カテゴリ自体に在庫あり商品があれば 'true'
2. なければ子カテゴリを再帰的にチェック
3. 子孫のどこかに在庫があれば 'true'、なければ 'false'
============================================================ #}
{% macro hasStockInTree(Category, CategoriesCountInStock) %}
{%- if CategoriesCountInStock[Category.id] is defined and CategoriesCountInStock[Category.id] > 0 -%}
true
{%- else -%}
{%- set found = 'false' -%}
{%- for ChildCategory in Category.children -%}
{%- if _self.hasStockInTree(ChildCategory, CategoriesCountInStock)|trim == 'true' -%}
{%- set found = 'true' -%}
{%- endif -%}
{%- endfor -%}
{{ found }}
{%- endif -%}
{% endmacro %}
{# ============================================================
マクロ: hasProductInTree
目的: カテゴリまたはその子孫カテゴリに商品があるか判定
引数:
- Category: 判定対象のカテゴリエンティティ
- CategoriesCount: カテゴリごとの全商品数の配列
戻り値: 'true' または 'false' (文字列)
ロジック:
1. 該当カテゴリ自体に商品があれば 'true'
2. なければ子カテゴリを再帰的にチェック
3. 子孫のどこかに商品があれば 'true'、なければ 'false'
============================================================ #}
{% macro hasProductInTree(Category, CategoriesCount) %}
{%- if CategoriesCount[Category.id] is defined and CategoriesCount[Category.id] > 0 -%}
true
{%- else -%}
{%- set found = 'false' -%}
{%- for ChildCategory in Category.children -%}
{%- if _self.hasProductInTree(ChildCategory, CategoriesCount)|trim == 'true' -%}
{%- set found = 'true' -%}
{%- endif -%}
{%- endfor -%}
{{ found }}
{%- endif -%}
{% endmacro %}
{# ============================================================
マクロ: tree
目的: カテゴリを再帰的にツリー表示
引数:
- Category: 表示対象のカテゴリエンティティ
- CategoriesCount: カテゴリごとの全商品数の配列
- CategoriesCountInStock: カテゴリごとの在庫あり商品数の配列
出力するHTML属性:
- data-count-all: 全商品数(JS用)
- data-count-stock: 在庫あり商品数(JS用)
- data-has-stock: 在庫有無フラグ(JS用)
- no-stock-category: 在庫なしカテゴリのCSSクラス
============================================================ #}
{% macro tree(Category, CategoriesCount, CategoriesCountInStock) %}
{% from _self import tree, hasStockInTree, hasProductInTree %}
{# カウント値を取得(未定義の場合は0) #}
{% set countAll = CategoriesCount[Category.id] is defined ? CategoriesCount[Category.id] : 0 %}
{% set countStock = CategoriesCountInStock[Category.id] is defined ? CategoriesCountInStock[Category.id] : 0 %}
{# カテゴリリンク
- data-count-all: JSで全商品数表示に切り替える際に使用
- data-count-stock: JSで在庫あり商品数表示に切り替える際に使用
- js-category-count: JSでカウント表示を更新するためのクラス #}
<a class="fs-6 js-category-link-sp" href="{{ url('product_list') }}?category_id={{ Category.id }}" data-count-all="{{ countAll }}" data-count-stock="{{ countStock }}">
{% if (Category.Parent == "") %}
<img class="menu-icon" src="/html/user_data/assets/img/category/{{ Category.id }}.png" alt="{{ Category.name }}">
{% endif %}
<span class="category-text">{{ Category.name }} (<span class="js-category-count">{{ countAll|number_format }}</span>)</span>
</a>
{% if Category.children|length > 0 %}
<ul>
{% for ChildCategory in Category.children %}
{# 子カテゴリの在庫判定(子孫含む) #}
{% set childHasStock = hasStockInTree(ChildCategory, CategoriesCountInStock)|trim %}
{# 子カテゴリの商品有無判定(子孫含む) #}
{% set childHasProduct = hasProductInTree(ChildCategory, CategoriesCount)|trim %}
{# no-stock-category: 在庫なしカテゴリを非表示にするためのクラス
no-product-category: 商品なしカテゴリを常に非表示にするためのクラス
data-has-stock: JSで在庫状態を判定するための属性 #}
<li class="{% if childHasStock == 'false' %}no-stock-category {% endif %}{% if childHasProduct == 'false' %}no-product-category{% endif %}" data-has-stock="{{ childHasStock }}">
{{ tree(ChildCategory, CategoriesCount, CategoriesCountInStock) }}
</li>
{% endfor %}
</ul>
{% endif %}
{% endmacro %}
{# マクロのインポート @see https://github.com/bolt/bolt/pull/2388 #}
{% from _self import tree, hasStockInTree, hasProductInTree %}
{# ============================================================
カテゴリナビゲーション本体
============================================================ #}
<div class="ec-headerCategoryArea">
<div class="ec-headerCategoryArea__heading">
<p>{{ 'カテゴリ一覧'|trans }}</p>
</div>
<div class="ec-itemNav">
<ul class="ec-itemNav__nav">
{% for Category in Categories %}
{# 在庫判定(子孫含む) #}
{% set hasStock = hasStockInTree(Category, CategoriesCountInStock)|trim %}
{# 商品有無判定(子孫含む) #}
{% set hasProduct = hasProductInTree(Category, CategoriesCount)|trim %}
{# トップレベルカテゴリのli要素
- no-stock-category: 在庫なしの場合に付与(JSで表示/非表示制御)
- no-product-category: 商品なしの場合に付与(常に非表示)
- data-has-stock: 在庫状態フラグ #}
<li class="{% if hasStock == 'false' %}no-stock-category {% endif %}{% if hasProduct == 'false' %}no-product-category{% endif %}" data-has-stock="{{ hasStock }}">
{{ tree(Category, CategoriesCount, CategoriesCountInStock) }}
</li>
{% endfor %}
</ul>
</div>
<div class="ec-headerCategoryArea__heading">
<p>{{ 'メーカー一覧'|trans }}</p>
</div>
<div class="ec-itemNav maker_list">
<ul class="ec-itemNav__nav">
{% for Maker in Makers %}
<li><a class='fs-6' href="{{ url('product_list') }}?maker_id={{ Maker.id }}">{{ Maker.name }}</a></li>
{% endfor %}
</ul>
<div class='py-2 px-2'>
<a href="{{ url('maker') }}"><button class='metroFamilyOrder-button01' type='button'>一覧を見る</button></a>
</div>
</div>
</div>