<?php
namespace Plugin\PiaZProduct\Event;
use Eccube\Event\EccubeEvents;
use Eccube\Event\EventArgs;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
/**
* 商品一覧検索イベントのサブスクライバー
*/
class ProductSearchEventSubscriber implements EventSubscriberInterface
{
/**
* @var RequestStack
*/
private $requestStack;
public function __construct(RequestStack $requestStack)
{
$this->requestStack = $requestStack;
}
/**
* @return array
*/
public static function getSubscribedEvents()
{
return [
EccubeEvents::FRONT_PRODUCT_INDEX_SEARCH => 'onProductIndexSearch',
];
}
/**
* 商品一覧検索イベントの処理
*
* @param EventArgs $event
*/
public function onProductIndexSearch(EventArgs $event)
{
$request = $this->requestStack->getCurrentRequest();
$searchData = $event->getArgument('searchData');
$qb = $event->getArgument('qb');
// セッションから検索条件を取得
$session = $request->getSession();
$sessionSearchData = $session->get('pia_z_product_search_data', []);
// セッションの検索条件を反映
if (!empty($sessionSearchData)) {
$this->applySessionSearchData($searchData, $qb, $sessionSearchData);
}
// 更新された検索データをイベントに設定
$event->setArgument('searchData', $searchData);
$event->setArgument('qb', $qb);
}
/**
* セッションの検索条件を適用
*
* @param array $searchData
* @param \Doctrine\ORM\QueryBuilder $qb
* @param array $sessionSearchData
*/
private function applySessionSearchData($searchData, $qb, $sessionSearchData)
{
// 商品名での検索
if (!empty($sessionSearchData['name'])) {
$qb->andWhere('p.name LIKE :session_name')
->setParameter('session_name', '%' . $sessionSearchData['name'] . '%');
}
// 商品コードでの検索
if (!empty($sessionSearchData['code'])) {
$qb->andWhere('pc.code LIKE :session_code')
->setParameter('session_code', '%' . $sessionSearchData['code'] . '%');
}
// カテゴリでの検索
if (!empty($sessionSearchData['category_id'])) {
$qb->andWhere('pc.category_id = :session_category_id')
->setParameter('session_category_id', $sessionSearchData['category_id']);
}
// 価格範囲での検索
if (!empty($sessionSearchData['price_min'])) {
$qb->andWhere('pc.price02 >= :session_price_min')
->setParameter('session_price_min', $sessionSearchData['price_min']);
}
if (!empty($sessionSearchData['price_max'])) {
$qb->andWhere('pc.price02 <= :session_price_max')
->setParameter('session_price_max', $sessionSearchData['price_max']);
}
// 在庫状況での検索
if (isset($sessionSearchData['stock_status'])) {
if ($sessionSearchData['stock_status'] === 'in_stock') {
$qb->andWhere('pc.stock > 0');
} elseif ($sessionSearchData['stock_status'] === 'out_of_stock') {
$qb->andWhere('pc.stock <= 0');
}
}
// 販売状況での検索
if (!empty($sessionSearchData['status'])) {
$qb->andWhere('p.Status = :session_status')
->setParameter('session_status', $sessionSearchData['status']);
}
// タグでの検索
if (!empty($sessionSearchData['tag'])) {
$qb->andWhere('pt.name LIKE :session_tag')
->setParameter('session_tag', '%' . $sessionSearchData['tag'] . '%');
}
// カスタム検索条件の追加
$this->applyCustomSearchConditions($searchData, $qb, $sessionSearchData);
}
/**
* カスタム検索条件の適用
*
* @param array $searchData
* @param \Doctrine\ORM\QueryBuilder $qb
* @param array $sessionSearchData
*/
private function applyCustomSearchConditions($searchData, $qb, $sessionSearchData)
{
// カスタムフィールドでの検索例
if (!empty($sessionSearchData['custom_field1'])) {
$qb->andWhere('p.custom_field1 LIKE :session_custom_field1')
->setParameter('session_custom_field1', '%' . $sessionSearchData['custom_field1'] . '%');
}
// 複数条件の組み合わせ例
if (!empty($sessionSearchData['complex_condition'])) {
$conditions = $sessionSearchData['complex_condition'];
if (isset($conditions['brand']) && !empty($conditions['brand'])) {
$qb->andWhere('p.brand = :session_brand')
->setParameter('session_brand', $conditions['brand']);
}
if (isset($conditions['material']) && !empty($conditions['material'])) {
$qb->andWhere('p.material LIKE :session_material')
->setParameter('session_material', '%' . $conditions['material'] . '%');
}
}
// 日付範囲での検索
if (!empty($sessionSearchData['date_from'])) {
$qb->andWhere('p.create_date >= :session_date_from')
->setParameter('session_date_from', $sessionSearchData['date_from']);
}
if (!empty($sessionSearchData['date_to'])) {
$qb->andWhere('p.create_date <= :session_date_to')
->setParameter('session_date_to', $sessionSearchData['date_to']);
}
}
}