CakePHP用検索プラグインfriendsofcake/searchで複数の検索設定を使い分ける

2018.11.11 php CakePHP

こんにちは、るかです。

CakePHP用の検索用プラグイン”friendsofcake/search”が使いやすかったので使わせてもらっています。

GitHub - FriendsOfCake/search: CakePHP: Easy model searching

インストールや使い方も簡単なのですが、1つのモデルに対して複数の検索設定をする方法メモ

バージョンはCakePHP3.6でう

基本的な使い方

基本的な使い方はGitHubのREADMEに詳しいですがインストールはComposer使います。

composer require friendsofcake/search

CakePHPのbinがあるディレクトリで

./bin/cake plugin load Search

そうするとCakeがプラグインロードしてくれます。 インストール自体はこれで終わり。

検索を使いたいTableファイルに設定をしていきます。

class ExamplesTable extends Table
{
    /**
     * @param array $config
     *
     * @return void
     */
    public function initialize(array $config)
    {
        parent::initialize($config);

        // ビヘイビアの追加
        $this->addBehavior('Search.Search');
    }

    /**
     * @return \Search\Manager
     */
    public function searchManager()
    {
        $searchManager = $this->behaviors()->Search->searchManager();
        $searchManager
            ->like('title')
            ->value('status');

        return $searchManager;
    }
}

ソースコードはGitHubのものを引用してます。 searchManager()っていう関数作ってその中に検索対象とするフィールド名とか条件とかを書いていきます。

class ExampleController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent("Search.Prg",[
            "actions" => ["index"] //検索を使うアクションを配列で指定
        ]);
    }

    public function index()
    {
        $filter = $this->request->getQuery();
        $query = $this->Examples->find("search", $filter);
        $example = $this->paginate($query);

        $this->set(compact("example"));
    }
}

コントローラーはこんな感じです。

1つのモデルに複数の検索条件を設定する

結論から言うとFilter collectionsを使います。

class ExamplesTable extends Table
{
    public function initialize(array $config)
    {
        parent::initialize($config);
        $this->addBehavior('Search.Search');
    }

    public function searchManager()
    {
        $searchManager = $this->behaviors()->Search->searchManager();
        $searchManager
            ->useCollection('setting1') // ここで1つ目の設定
            ->like('title')
            ->value('status')
            ->useCollection('setting2') // ここで2つ目の設定
            ->like('title2')
            ->value('status2');

        return $searchManager;
    }
}

useCollectionにコレクション名を指定します。 その後に検索で使う設定などを記述していき、続けてuseCollectionを書くとそこまでが1つの設定群になりコレクション名で呼び出せるようになります。

class ExampleController extends Controller
{
    public function initialize()
    {
        parent::initialize();
        $this->loadComponent("Search.Prg",[
            "actions" => ["index"] //検索を使うアクションを配列で指定
        ]);
    }

    public function index()
    {
        $filter = $this->request->getQuery();
        // findの第二引数にcollection名を連想配列で渡すことで設定を切り替えられます。
        $query = $this->Examples
        ->find('search', ['search' => $this->request->query, 'collection' => 'setting1']);
        $example = $this->paginate($query);

        $this->set(compact("example"));
    }
}

コントローラーはこんな感じになります。 これでアクションごとに同じモデルで検索の振る舞いを自由に変えることができるようになります。