5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

EC-CUBE4 リポジトリのカスタマイズ 使い方を調べてみた

Last updated at Posted at 2021-01-15

#リポジトリのカスタマイズって?

リポジトリカスタムのドキュメント

ドキュメントにある程度説明がありますが、ぶっちゃけよくわからんです。
わからんので、使っていなかったのですが、頑張って使ってみると意外に簡単。

実装例が1つしかなく、難しく感じたので使い方を調べてみました。

ここでカスタム出来るリポジトリは基本的に検索系だけですが、EccubeEventsを使ってのカスタムは非推奨なので、出来るだけこのカスタム方法を使いましょう。

#カスタム出来るリポジトリクラス
(リストはドキュメントから)

リポジトリクラス QueryKey
ProductRepository::getQueryBuilderBySearchData() QueryKey::PRODUCT_SEARCH
ProductRepository::getQueryBuilderBySearchDataForAdmin() QueryKey::PRODUCT_SEARCH_ADMIN
ProductRepository::getFavoriteProductQueryBuilderByCustomer() QueryKey::PRODUCT_GET_FAVORITE
CustomerRepository::getQueryBuilderBySearchData() QueryKey::CUSTOMER_SEARCH
OrderRepository::getQueryBuilderBySearchData() QueryKey::ORDER_SEARCH
OrderRepository.getQueryBuilderBySearchDataForAdmin() QueryKey::ORDER_SEARCH_ADMIN
OrderRepository::getQueryBuilderByCustomer() QueryKey::ORDER_SEARCH_BY_CUSTOMER

利用画面

QueryKey 利用画面
QueryKey::PRODUCT_SEARCH フロント:商品一覧
QueryKey::PRODUCT_SEARCH_ADMIN 管理画面:商品一覧、受注登録・編集の商品追加の商品検索
QueryKey::PRODUCT_GET_FAVORITE 関数が無い。
QueryKey::CUSTOMER_SEARCH 管理画面:会員一覧、受注登録・編集の会員検索
QueryKey::ORDER_SEARCH 関数が無い。
QueryKey::ORDER_SEARCH_ADMIN 管理画面:受注一覧
QueryKey::ORDER_SEARCH_BY_CUSTOMER フロント:マイページ・購入一覧

2つ関数が無いものがありました。。。

#カスタマイズするためのインターフェイス

(リストはドキュメントから)

インターフェイス/クラス 概要
QueryCustomizer QueryBuilderを自由に変更
OrderByCustomizer ソート順を変更する
WhereCustomizer 検索条件を追加する
JoinCustomizer 結合するテーブルを追加する

カスタマイズするために、上記から必要な物を利用します。
自分的には、QueryBuilderを自由に変更できるQueryCustomizerを覚えておけば良いのではないかと思ってます。

ではでは、使い方を見ていきましょう。

#カスタマイズ例
##OrderByCustomizer(ソート順を変更する)

OrderByCustomizerはソート順だけ変更できます。
orderBy、複数設定した場合は、2つ目以降はaddOrderByになります。

###実装例
(実装例はドキュメントから:常に商品IDでソートするサンプル)


<?php

namespace Customize\Repository;

use Eccube\Doctrine\Query\OrderByClause;
use Eccube\Doctrine\Query\OrderByCustomizer;
use Eccube\Repository\QueryKey;

class AdminProductListCustomizer extends OrderByCustomizer
{
    /**
     * 常に商品IDでソートする。
     *
     * @param array $params
     * @param $queryKey
     * @return OrderByClause[]
     */
    protected function createStatements($params, $queryKey)
    {
        return [new OrderByClause('p.id')];
    }

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

###降順にする
降順にしたい場合は、OrderByClauseの第二引数に「desc」を設定しましょう。


<?php

protected function createStatements($params, $queryKey)
{
    return [new OrderByClause('p.id','desc')];
}

###複数設定
複数設定する場合は「new OrderByClause」を追加してやればOKです。
意味ないですが、idでソートした後に、商品名でソートする場合。


<?php

protected function createStatements($params, $queryKey)
{
    return [
        new OrderByClause('p.id'),
        new OrderByClause('p.name'),
    ];
}

以上です。

##WhereCustomizer(検索条件を追加)

条件はすべてandWhereされます。

###実装例
(実装例:常に商品名が商品の物だけ表示する)
これやると商品名が商品の物以外の商品が表示されなくなります。あまりいい例題が思い浮かばない。。。


<?php

namespace Customize\Repository;

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

class AdminProductListCustomizer extends WhereCustomizer
{
    /**
     * 常に商品名が商品の物だけ表示する
     *
     * @param array $params
     * @param $queryKey
     * @return WhereClause[]
     */
    protected function createStatements($params, $queryKey)
    {
        return [WhereClause::eq('p.name', ':name', ['name' => '商品'])];
    }

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

###複数設定する
複数設定する場合は「WhereClause」を追加してやればOKです。


<?php

protected function createStatements($params, $queryKey)
{
    return [
        WhereClause::eq('p.name', ':name', ['name' => 'hoge']),
        WhereClause::eq('p.name', ':name', ['name' => 'hogehoge']),
    ];
}

条件ごとの関数は以下になります。

###条件例
参考:WhereClause.php


//=
WhereClause::eq('name', ':Name', 'hoge')
WhereClause::eq('name', ':Name', ['Name' => 'hoge'])

//<>
WhereClause::neq('name', ':Name', 'hoge')
WhereClause::neq('name', ':Name', ['Name' => 'hoge'])

//IS NULL
WhereClause::isNull('name')

//IS NOT NULL
WhereClause::isNotNull('name')

//LIKE
WhereClause::like('name', ':Name', '%hoge')
WhereClause::like('name', ':Name', ['Name' => '%hoge'])

//NOT LIKE
WhereClause::notLike('name', ':Name', '%hoge')
WhereClause::notLike('name', ':Name', ['Name' => '%hoge'])

//IN
WhereClause::in('name', ':Names', ['foo', 'bar'])
WhereClause::in('name', ':Names', ['Names' => ['foo', 'bar']])

//NOT IN
WhereClause::notIn('name', ':Names', ['foo', 'bar'])
WhereClause::notIn('name', ':Names', ['Names' => ['foo', 'bar']])

//BETWEEN
WhereClause::between('price', ':PriceMin', ':PriceMax', [1000, 2000])
WhereClause::between('price', ':PriceMin', ':PriceMax', ['PriceMin' => 1000, 'PriceMax' => 2000])

//>
WhereClause::gt('price', ':Price', 1000)
WhereClause::gt('price', ':Price', ['Price' => 1000])

//>=
WhereClause::gte('price', ':Price', 1000)
WhereClause::gte('price', ':Price', ['Price' => 1000])

//<
WhereClause::lt('price', ':Price', 1000)
WhereClause::lt('price', ':Price', ['Price' => 1000])

//<=
WhereClause::lte('price', ':Price', 1000)
WhereClause::lte('price', ':Price', ['Price' => 1000])

以上です。

##JoinCustomizer(結合するテーブルを追加する)
参考:JoinClause.php

###実装例
(実装例:常に商品に代理店情報を接続して代理店名で検索する。)

前提として、EntityにAgency(代理店情報)を追加カスタムしている事を想定します。
ProductTraitにManyToOneでAgencyとつなげてると想定します。
FromTypeに「agency」を追加していると想定します。


<?php

namespace Customize\Repository;

use Eccube\Doctrine\Query\JoinClause;
use Eccube\Doctrine\Query\WhereClause;
use Eccube\Doctrine\Query\JoinCustomizer;
use Eccube\Repository\QueryKey;

class AdminProductListCustomizer extends JoinCustomizer
{
    /**
     * 常に商品に代理店情報を接続して代理店名で検索する。
     *
     * @param array $params
     * @param $queryKey
     * @return JoinClause[]
     */
    protected function createStatements($params, $queryKey)
    {
        $Obj = JoinClause::leftJoin('p.Agency', 'a');
        $Obj->addWhere(WhereClause::eq('a.name', ':agency_name', ['agency_name' => $params['agency']]));
        return [$Obj];
    }

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

###Joinする
まずは、「innerJoin」「leftJoin」で「JoinClause」のオブジェクトが返ってきます。


$Obj = JoinClause::innerJoin($join, $alias);
$Obj = JoinClause::leftJoin($join, $alias);

###条件とソート
「addWhere」に「WhereClause」のオブジェクトを、「addOrderBy」に「OrderByClause」のオブジェクトを渡してやることによって、検索条件やソート条件を追加できます。


use Eccube\Doctrine\Query\OrderByClause;
use Eccube\Doctrine\Query\WhereClause;

$Obj->addWhere(WhereClause::eq('name', ':Name', ['Name' => 'hoge']));
$Obj->addOrderBy(new OrderByClause('p.id'));

「createStatements」で複数のオブジェクトを配列れreturnすれば、複数のjoinができます。

以上。

##QueryCustomizer(QueryBuilderを自由に変更)

EC-CUBE4のQueryCustomizerでOR条件を追加したい場合

こちらの記事をどうぞー!!!

以上。

#最後に

実装例が良くないので、理解するまで時間かかるかもですが、参考なれば幸いです。

ここが分かり難いぞーなどあればコメントください。

5
8
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
8

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?