[EC-CUBE4]タグIDで商品一覧を絞り込めるようにするよー

商品に紐づいたタグで商品一覧を絞り込みたいことありませんか?

example.com/products/list?category_id=2&tag_id=1

みたいにtag_id=Xで商品一覧を絞り込めるようにしたいと思います。

1.app/Customize/Form/Extension/SearchProductTypeExtension.phpを作成

<?php
namespace Customize\Form\Extension;
 
use Eccube\Form\Type\SearchProductType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\Extension\Core\Type\HiddenType;
use Symfony\Component\Form\FormBuilderInterface;
 
class SearchProductTypeExtension extends AbstractTypeExtension
{ 
     /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('tag_id', HiddenType::class, []);
    }

    /**
     * {@inheritdoc}
     */
    public function getExtendedType()
    {
        return SearchProductType::class;
    }
}

2.app/Customize/Repository/TagIdSearchCustomizer.phpを作成

<?php
 
namespace Customize\Repository;
 
use Eccube\Doctrine\Query\QueryCustomizer;
use Eccube\Repository\QueryKey;
use Doctrine\ORM\QueryBuilder;
 
/**
 * 
 */
class TagIdSearchCustomizer implements QueryCustomizer {
 
    /**
     * 検索のパラメータにtag_idを追加
     */
    public function customize(QueryBuilder $builder, $params, $queryKey)
    {
        if (!empty($params['tag_id']) && $params['tag_id']) {
            $builder->innerJoin('p.ProductTag', 'pt');
            $builder->andWhere('pt = :tag_id');
            $builder->setParameter('tag_id', $params['tag_id']);
        }
    }
 
    public function getQueryKey(): string
    {
        return QueryKey::PRODUCT_SEARCH;
    }
 
}

上記の2ファイルを設置すれば商品一覧でtag_idを使えるようになります。

解説

SearchProductTypeExtensionについて

FormTypeのカスタマイズ
FormExtensionを使った拡張

Form Typeのカスタマイズは上記URLです。

src配下に存在しているSearchProductTypeが商品一覧のFormを定義しているファイルなんですね。それを拡張するということをgetExtendedTypeで指定していて、buildFormでtag_idをhiddenとして定義しています。

TagIdSearchCustomizer.phpについて

リポジトリのカスタマイズ
QueryBuilderの拡張 #2285, #2298

上記のページでRepositoryのカスタマイズ方法が記載されています。

ProductRepository::getQueryBuilderBySearchData()をカスタマイズするためにgetQueryKeyでreturn QueryKey::PRODUCT_SEARCH;としています。

tag_idというパラメータが存在した場合は、ProductTagとinner joinして結果を絞り込むようにしています。

コメント

タイトルとURLをコピーしました