ECCUBE4

EC-CUBE4 商品検索のカスタマイズ

本記事では、商品一覧の検索条件に価格下限、価格上限」を追加してみます。

商品検索はデフォルで、商品ID、商品名、商品コード、カテゴリー、公開ステータス、在庫有無、登録日、更新日の検索条件が存在します。

商品検索のフォームを作成

フォーム(Extensionファイル)の作成

まず、Extensionファイルを作成ます。このExtensionで、商品検索のフォームの実体(src/Eccube/Form/Type/Admin/SearchProductType.php)を拡張します。

<?php

namespace Plugin\ProductSearchCustomize\Form\Extension\Admin;

use Eccube\Form\Type\PriceType;
use Symfony\Component\Form\AbstractTypeExtension;
use Symfony\Component\Form\FormBuilderInterface;
use Eccube\Form\Type\Admin\SearchProductType;

class SearchProductExtension extends AbstractTypeExtension
{
    /**
     * {@inheritdoc}
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('lower_price', PriceType::class, [
                'required' => false,
            ])->add('upper_price', PriceType::class, [
                'required' => false,
            ]);
    }

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

Twigファイルを作成

次に先ほど、拡張したExtensionを表示するためのTwigを作成します。

<script type="text/javascript">
    $(function () {

        // append to layout
        $("#searchDetail").children().find('.col-6').eq(2).append($("#search_price"));
    })
</script>

<div class="mb-2" id="search_price">
    <div class="form-row align-items-center">
        <div class="col">
            <label class="col-form-label">{{ 'admin.pluign.product_search_customize.lower_pirce.title'|trans }}</label>
            {{ form_widget(searchForm.lower_price) }}
            {{ form_errors(searchForm.lower_price) }}
        </div>
        <div class="col-auto"><span>{{ 'admin.common.separator__range'|trans }}</span></div>
        <div class="col">
            <label class="col-form-label">{{ 'admin.pluign.product_search_customize.uppper_price.title'|trans }}</label>
            {{ form_widget(searchForm.upper_price) }}
            {{ form_errors(searchForm.upper_price) }}
        </div>
    </div>
</div>

翻訳ファイルに追記

admin.pluign.product_search_customize.lower_pirce.title: 下限価格
admin.pluign.product_search_customize.uppper_price.title: 上限価格

Event.phpを編集

次にEvent.phpで先ほど作成したTwigファイルを商品一覧が表示された時に、追加して表示するようにします。

<?php

namespace Plugin\ProductSearchCustomize;

use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Eccube\Event\TemplateEvent;

class Event implements EventSubscriberInterface
{
    /**
     * @return array
     */
    public static function getSubscribedEvents()
    {
        return [
            '@admin/Product/index.twig' => 'searchCustomize',
        ];
    }

    public function searchCustomize(TemplateEvent $event)
    {
        $event->addSnippet('@ProductSearchCustomize/admin/Product/index.twig');
    }
}

検索機能を拡張

先ほど作成した価格下限と価格上限のフォームから値が入力されたら、検索条件に盛り込むようにソースコードを変更していきます。

EC-CUBE4ではデータベースからデータを取得するにはRepositry機能を使います、そして、既存の商品検索機能に条件を追加する事ができます。

<?php

namespace Plugin\ProductSearchCustomize\Repository\Admin\Product;

use Eccube\Doctrine\Query\WhereCustomizer;
use Eccube\Doctrine\Query\WhereClause;
use Eccube\Repository\QueryKey;

class SearchDataForAdminCustomizer extends WhereCustomizer
{
    /**
     * @param array $params
     * @param $queryKey
     *
     * @return WhereClause[]
     */
    public function createStatements($params, $queryKey)
    {
        if ($params['lower_price'] && $params['upper_price']) {
            return [WhereClause::between('pc.price02', ':PriceMin', ':PriceMax', [$params['lower_price'], $params['upper_price']])];
        } elseif ($params['lower_price'] && empty($params['upper_price'])) {
            return [ WhereClause::gte('pc.price02', ':Price', $params['lower_price']) ];
        } elseif (empty($params['lower_price']) && $params['upper_price']) {
            return [ WhereClause::lte('pc.price02', ':Price', $params['upper_price']) ];
        }
        return [];
    }

    /**
     * ProductRepository::getQueryBuilderBySearchDataForAdmin に適用する.
     *
     * @return string
     * @see \Eccube\Repository\ProductRepository::getQueryBuilderBySearchDataForAdmin()
     * @see QueryKey
     */
    public function getQueryKey()
    {
        return QueryKey::PRODUCT_SEARCH_ADMIN;
    }
}

完成

次の画像のように、表示されていて、検索が聞いていれば問題なしです。