要望や症状
商品カテゴリページから検索を実行すると、そのカテゴリ内の商品のみが検索対象となり、サイト全体の商品から検索することができません。
具体的な動作について
TOPページの検索バーを使用した場合は全商品から検索が可能です。しかし、商品カテゴリページに移動してから検索バーで検索を実行すると、現在表示中のカテゴリ内の商品のみが検索対象となってしまいます。この際、検索バー左側のカテゴリ選択部分が自動的に現在のカテゴリに固定される状態となります。
理由や原因
この問題は、EC-CUBEの標準仕様による動作です。商品カテゴリページで検索を実行する際、現在表示中のカテゴリIDが検索条件として自動的に設定される仕組みが実装されています。
この動作は、検索フォームのテンプレートまたは検索処理のコントローラにおいて、現在のページコンテキスト(カテゴリID)を検索パラメータとして引き継ぐ実装が行われているためです。これは、ユーザビリティの観点から、カテゴリページでは関連商品の検索を促進する設計思想に基づいています。
解決策
検索フォームテンプレートの修正
最も基本的な解決方法として、検索フォーム部分のTwigテンプレートをカスタマイズして、カテゴリ指定を常に無効化します。
{# app/template/default/Block/search_product.twig #}
<div class="ec-searchnavRole">
<form name="search_product_form" id="search_product_form" method="get" action="{{ url('product_list') }}">
<div class="ec-searchnavRole__infos">
<div class="ec-searchnavRole__category">
<div class="ec-select">
<select name="category_id" class="ec-select__select">
<option value="">{{ 'すべての商品' }}</option>
{% for Category in Categories %}
<option value="{{ Category.id }}">{{ Category.name }}</option>
{% endfor %}
</select>
</div>
</div>
<div class="ec-searchnavRole__keyword">
<input type="text" class="ec-searchnavRole__keywordInput" name="name" value="{{ search_form.name.vars.value|default('') }}" placeholder="キーワードを入力">
</div>
<div class="ec-searchnavRole__btn">
<button type="submit" class="ec-searchnavRole__btn--search">{{ '検索する' }}</button>
</div>
</div>
</form>
</div>
JavaScriptによる制御
より確実にカテゴリ選択を無効化したい場合は、JavaScriptを使用して制御することも可能です。
// app/template/default/default_frame.twig の <script> セクション内
document.addEventListener('DOMContentLoaded', function() {
// 検索フォームのカテゴリセレクトボックスを常に「すべての商品」に設定
const categorySelect = document.querySelector('select[name="category_id"]');
if (categorySelect) {
categorySelect.value = '';
// セレクトボックス自体を非表示にする場合
// categorySelect.closest('.ec-searchnavRole__category').style.display = 'none';
}
});
検索コントローラのカスタマイズ(上級者向け)
より根本的な解決方法として、検索処理のコントローラをイベントリスナーで拡張する方法があります。
// app/Customize/EventListener/SearchListener.php
<?php
namespace Customize\EventListener;
use Eccube\Event\TemplateEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class SearchListener implements EventSubscriberInterface
{
public static function getSubscribedEvents()
{
return [
'Product/list.twig' => 'onProductList',
];
}
public function onProductList(TemplateEvent $event)
{
// 検索フォームのカテゴリ指定を無効化するJavaScriptを追加
$source = $event->getSource();
$script = '
<script>
document.addEventListener("DOMContentLoaded", function() {
const categorySelect = document.querySelector("select[name=\'category_id\']");
if (categorySelect) {
categorySelect.value = "";
}
});
</script>';
$source = str_replace('</body>', $script . '</body>', $source);
$event->setSource($source);
}
}
設定の反映
カスタマイズした内容を確実に反映させるため、以下のコマンドを実行してキャッシュをクリアします。
# 開発環境のキャッシュクリア
bin/console cache:clear
# 本番環境のキャッシュクリア
bin/console cache:clear --env=prod
上記の方法により、商品カテゴリページからでもサイト全体の商品を対象とした検索が可能となります。