EC-CUBE Lab
produced by Cajiya
EC-CUBEに関するカスタマイズ方法やトラブルへの対処方法を発信

カテゴリーの一覧から、商品が紐づいていないカテゴリーのみを非表示にするカスタマイズ方法

公開日: 2025年10月12日 | 更新日: 2025年11月08日
商品カテゴリ・一覧・検索 表示/テンプレート調整 EC-CUBE 4系全般 Twig改修

要望や症状

子カテゴリー一覧を表示する際に、商品が登録されていないカテゴリーも表示されてしまう問題が発生します。

現在のコード

現在のTwigテンプレートでは以下のようにカテゴリーを表示しています。

{% set Category = repository('Eccube\Entity\Category').find(11) %}
{% set cate_childs = Category.getDescendants %}
{% if cate_childs %}
{% set h = Category.hierarchy + 1 %}
<ul>
{% for cate in cate_childs %}
{% if h == cate.hierarchy %}
<li><a href="{{ url('product_list') }}?category_id={{ cate.id }}">{{ cate.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endif %}

このコードでは商品の有無に関係なく、すべての子カテゴリーが表示されます。

理由や原因

現在のTwigテンプレートでは、カテゴリーの階層構造のみを参照しており、各カテゴリーに紐づく商品の存在確認を行っていないためです。

EC-CUBE標準では、カテゴリーと商品の関連はProductCategoryエンティティを介した多対多の関係で管理されており、商品の公開ステータスも考慮する必要があります。

解決策

商品が存在しないカテゴリーを非表示にする方法として、以下の2つのアプローチがあります。

方法1: リアルタイム判定(小規模サイト向け)

Twigテンプレートで商品の存在を動的に確認する方法です。

{% set Category = repository('Eccube\Entity\Category').find(11) %}
{% set cate_childs = Category.getDescendants %}
{% if cate_childs %}
{% set h = Category.hierarchy + 1 %}
<ul>
{% for cate in cate_childs %}
{% if h == cate.hierarchy %}
{% set product_count = repository('Eccube\Entity\Product').createQueryBuilder('p')
    .select('COUNT(p.id)')
    .innerJoin('p.ProductCategories', 'pc')
    .where('pc.Category = :category')
    .andWhere('p.Status = :status')
    .setParameter('category', cate)
    .setParameter('status', constant('Eccube\\Entity\\Master\\ProductStatus::DISPLAY_SHOW'))
    .getQuery()
    .getSingleScalarResult() %}
{% if product_count > 0 %}
<li><a href="{{ url('product_list') }}?category_id={{ cate.id }}">{{ cate.name }}</a></li>
{% endif %}
{% endif %}
{% endfor %}
</ul>
{% endif %}

方法2: 事前集計方式(大規模サイト向け)

商品数をカテゴリーテーブルに事前保存する方法です。まずマイグレーションを作成します。

// app/DoctrineMigrations/VersionXXXXXXXXXXXXXX.php
use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class VersionXXXXXXXXXXXXXX extends AbstractMigration
{
    public function up(Schema $schema): void
    {
        $this->addSql('ALTER TABLE dtb_category ADD product_count INT DEFAULT 0');
    }

    public function down(Schema $schema): void
    {
        $this->addSql('ALTER TABLE dtb_category DROP COLUMN product_count');
    }
}

カテゴリーエンティティの拡張

// app/Customize/Entity/Category.php
namespace Customize\Entity;

use Doctrine\ORM\Mapping as ORM;
use Eccube\Entity\Category as BaseCategory;

if (!class_exists('\Customize\Entity\Category')) {
    /**
     * @ORM\Entity
     * @ORM\Table(name="dtb_category")
     */
    class Category extends BaseCategory
    {
        /**
         * @var int
         *
         * @ORM\Column(name="product_count", type="integer", options={"default":0})
         */
        private $product_count = 0;

        public function getProductCount(): int
        {
            return $this->product_count;
        }

        public function setProductCount(int $product_count): self
        {
            $this->product_count = $product_count;
            return $this;
        }
    }
}

商品数更新用コマンドの作成

// app/Customize/Command/UpdateCategoryProductCountCommand.php
namespace Customize\Command;

use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;
use Doctrine\ORM\EntityManagerInterface;
use Eccube\Repository\CategoryRepository;
use Eccube\Repository\ProductRepository;
use Eccube\Entity\Master\ProductStatus;

class UpdateCategoryProductCountCommand extends Command
{
    protected static $defaultName = 'app:update-category-product-count';
    
    private $entityManager;
    private $categoryRepository;
    private $productRepository;

    public function __construct(
        EntityManagerInterface $entityManager,
        CategoryRepository $categoryRepository,
        ProductRepository $productRepository
    ) {
        $this->entityManager = $entityManager;
        $this->categoryRepository = $categoryRepository;
        $this->productRepository = $productRepository;
        parent::__construct();
    }

    protected function execute(InputInterface $input, OutputInterface $output): int
    {
        $categories = $this->categoryRepository->findAll();
        
        foreach ($categories as $category) {
            $qb = $this->productRepository->createQueryBuilder('p')
                ->select('COUNT(p.id)')
                ->innerJoin('p.ProductCategories', 'pc')
                ->where('pc.Category = :category')
                ->andWhere('p.Status = :status')
                ->setParameter('category', $category)
                ->setParameter('status', ProductStatus::DISPLAY_SHOW);
            
            $count = $qb->getQuery()->getSingleScalarResult();
            $category->setProductCount($count);
        }
        
        $this->entityManager->flush();
        $output->writeln('Category product counts updated successfully.');
        
        return Command::SUCCESS;
    }
}

更新したTwigテンプレート

{% set Category = repository('Eccube\Entity\Category').find(11) %}
{% set cate_childs = Category.getDescendants %}
{% if cate_childs %}
{% set h = Category.hierarchy + 1 %}
<ul>
{% for cate in cate_childs %}
{% if h == cate.hierarchy and cate.product_count > 0 %}
<li><a href="{{ url('product_list') }}?category_id={{ cate.id }}">{{ cate.name }}</a></li>
{% endif %}
{% endfor %}
</ul>
{% endif %}

定期実行の設定

cronを使用して定期的に商品数を更新します。

# 毎日深夜2時に実行
0 2 * * * cd /path/to/eccube && php bin/console app:update-category-product-count

注意事項

方法1はページ表示のたびにデータベースクエリが実行されるため、商品数やカテゴリー数が多い場合はパフォーマンスが大幅に低下する可能性があります。

方法2では商品の登録・削除・ステータス変更時にも商品数の更新が必要になる場合があります。

本体ファイルの直接変更は避け、Customizeディレクトリでの拡張を推奨します。

免責事項

本記事に掲載しているコードや手順は、執筆時点での情報および特定の環境下での動作確認に基づいています。 EC-CUBEのバージョン、サーバー環境、導入済みプラグインとの競合などにより、予期せぬ不具合が発生する可能性があります。

本記事の内容を実行した結果、生じた損害(データの消失、サイトの停止、機会損失など)について、当サイトおよび管理者は一切の責任を負いかねます。 実装にあたっては、必ずバックアップを取得し、検証環境(テスト環境)での動作確認を行った上で、ご自身の責任において実施してください。

この記事は参考になりましたか?

著者プロフィール: 株式会社カジヤ

当社はWeb業界の専門家として、培った経験や技術、自社事業を通して得た知見を土台に、 お客様の事業の成長を後押しすることを提供価値として活動する、Web事業の成長支援会社です。 EC-CUBE公式のパートナー制度「EC-CUBE インテグレートパートナー」に登録してしており、上位11%にあたる「ゴールドランク」に認定された実績があり、新しい通販サイトの構築から、カスタマイズ、リニューアルまで幅広く対応します。

商品カテゴリ・一覧・検索 の関連記事

商品カテゴリ・一覧・検索 機能不動作 EC-CUBE 4系全般
カテゴリ削除ボタンがグレーアウトして削除できない場合の対処法

EC-CUBEの商品管理でカテゴリ管理画面を開いた際に、削除したいカテゴリの削除ボタン(×)がグレー...

👍 0 / 👎 0 2025年10月12日
商品カテゴリ・一覧・検索 表示/テンプレート調整 EC-CUBE 4系全般
特定カテゴリのでのみHTMLを表示するTwigのカスタマイズ方法

特定のカテゴリの商品一覧ページでのみHTMLやメッセージを表示したいが、商品一覧のTwigテンプレー...

👍 0 / 👎 0 2025年10月12日
商品カテゴリ・一覧・検索 検索・絞り込み強化 EC-CUBE 4系全般
商品検索のカテゴリ制限を解除するカスタマイズ方法

商品カテゴリページから検索を実行すると、そのカテゴリ内の商品のみが検索対象となり、サイト全体の商品か...

👍 0 / 👎 0 2025年09月24日

表示/テンプレート調整 の関連記事

商品 表示/テンプレート調整 EC-CUBE 4系全般
会員のみに商品価格を表示するカスタマイズ方法

EC-CUBEで会員専用サイトや卸売りサイトを構築する際、商品価格をログイン前は非表示にし、会員ログ...

👍 0 / 👎 0 2025年10月12日
受注管理(管理画面) 表示/テンプレート調整 EC-CUBE 4系全般
受注一覧ページで会員番号を表示するカスタマイズ方法

管理画面の受注一覧ページで、注文者の会員番号を表示したい場合があります。 ### 表示要件 ...

👍 0 / 👎 0 2025年10月12日
商品カテゴリ・一覧・検索 表示/テンプレート調整 EC-CUBE 4系全般
特定カテゴリのでのみHTMLを表示するTwigのカスタマイズ方法

特定のカテゴリの商品一覧ページでのみHTMLやメッセージを表示したいが、商品一覧のTwigテンプレー...

👍 0 / 👎 0 2025年10月12日
管理画面共通 表示/テンプレート調整 EC-CUBE 4系全般
管理画面左上のEC-CUBEロゴをカスタマイズする方法

管理画面の左上に表示されているEC-CUBEのデフォルトロゴを、自社のロゴに変更したいと考えています...

👍 0 / 👎 0 2025年10月12日
マイページ全般 表示/テンプレート調整 EC-CUBE 4系全般
マイページにメール受信履歴ページをカスタマイズする方法

マイページに注文関連のメール履歴を一覧表示する専用ページを作成したいという要望があります。現在のEC...

👍 0 / 👎 0 2025年10月12日

EC-CUBE 4系全般 の関連記事

商品 データ不整合 EC-CUBE 4系全般
EC-CUBEで取り扱い終了商品の削除ができない理由と対応方法

EC-CUBEでは、取り扱いを終了した商品を削除したい場合に、削除ができない状態になることがあります...

👍 1 / 👎 0 2025年10月12日
インストール・セットアップ EC-CUBE 4系全般 設定変更
EC-CUBEサイトのドメイン変更時の設定変更方法

EC-CUBEで構築したサイトを新しいドメインで公開する際に、どのような設定変更が必要かわからない場...

👍 0 / 👎 0 2025年10月12日
メール通知 通知/コミュニケーション EC-CUBE 4系全般
メール件名のショップ名を英語表記に変更する方法

EC-CUBE 4系で、メール件名の先頭に自動挿入される店舗名を英語表記に変更したい場合があります。...

👍 0 / 👎 0 2025年10月12日
フロント共通 機能不動作 EC-CUBE 4系全般
CloudFrontを利用時にリンクのドメインがEC2のパブリックDNSになってしまう問題の解決方法

EC-CUBE 4.2をAWS ECS on EC2上で構築し、CloudFrontをCDNとして利...

👍 1 / 👎 0 2025年10月12日
サイト全体 500エラー EC-CUBE 4系全般
EC-CUBEでメモリ不足エラーが発生した場合の対処方法

EC-CUBEの運用中に以下のようなメモリ不足エラーが発生することがあります。 ### エラー...

👍 1 / 👎 0 2025年10月12日

Twig改修 の関連記事

商品 表示/テンプレート調整 EC-CUBE 4系全般
会員のみに商品価格を表示するカスタマイズ方法

EC-CUBEで会員専用サイトや卸売りサイトを構築する際、商品価格をログイン前は非表示にし、会員ログ...

👍 0 / 👎 0 2025年10月12日
受注管理(管理画面) 表示/テンプレート調整 EC-CUBE 4系全般
受注一覧ページで会員番号を表示するカスタマイズ方法

管理画面の受注一覧ページで、注文者の会員番号を表示したい場合があります。 ### 表示要件 ...

👍 0 / 👎 0 2025年10月12日
帳票 帳票/出力 EC-CUBE 4系全般
納品書にお客様からのお問い合わせを表示するカスタマイズ方法

EC-CUBE 4.2.2のデフォルトの納品書出力機能では、お客様からのお問い合わせ内容(備考欄)が...

👍 0 / 👎 0 2025年10月12日
商品カテゴリ・一覧・検索 表示/テンプレート調整 EC-CUBE 4系全般
特定カテゴリのでのみHTMLを表示するTwigのカスタマイズ方法

特定のカテゴリの商品一覧ページでのみHTMLやメッセージを表示したいが、商品一覧のTwigテンプレー...

👍 0 / 👎 0 2025年10月12日
商品 EC-CUBE 4.2系 / Symfony 5.4 Twig改修
商品画像の登録枚数の上限数を変更する方法

EC-CUBE 4.2系の管理画面で商品登録を行う際、商品画像が10枚までしか登録できない制限があり...

👍 0 / 👎 0 2025年10月12日