#リポジトリのカスタマイズって?
ドキュメントにある程度説明がありますが、ぶっちゃけよくわからんです。
わからんので、使っていなかったのですが、頑張って使ってみると意外に簡単。
実装例が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条件を追加したい場合
こちらの記事をどうぞー!!!
以上。
#最後に
実装例が良くないので、理解するまで時間かかるかもですが、参考なれば幸いです。
ここが分かり難いぞーなどあればコメントください。