商品に紐づいたタグで商品一覧を絞り込みたいことありませんか?
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して結果を絞り込むようにしています。
コメント