CakePHP 検索プラグイン「Search Plugin」の検索条件サンプルいろいろ

言わずと知れたCakePHPの検索プラグイン「Search Plugin」

高度な検索機能はもちろんのこと、検索結果にもページネーションを引き継いでくれる便利なプラグインです。
「これは入れとくべし!」なプラインのひとつですね。

CakeDC / search

ということで、検索条件サンプルをいくつか載せておきたいと思います。

プラグインのインストール

CakeDC / search からプラグインをダウンロードします。
※CakePHPのバージョンに合ったver.をダウンロードしましょう。最新版は CakePHP 2.0 Stable 用です。

ダウンロードしたプラグインフォルダの名前を「search」にリネームして、app/plugins フォルダに入れます。

サンプルアプリケーション

タイトル(Post.title)、本文(Post.body)、投稿者(User.username)を表示する掲示板で、モデルは、Posts belongsTo Users のアソシエーション関係にあります。

特定フィールドの部分一致検索

タイトル(Post.title フィールド)の部分一致検索

モデル

ビヘイビアを読み込んで、検索条件を記述します。
部分一致検索なので ‘type’ => ‘like’ とします。

> post.php

class Post extends AppModel {
	public $actsAs = array('Search.Searchable');
	public $belongsTo = array('User');
	public $filterArgs = array(
		array('name' => 'title', 'type' => 'like'),
	);
}

コントローラ

コンポーネントを読み込んで、検索結果を表示する find メソッドを追加します。

> posts_controller.php

class PostsController extends AppController {
	public $components = array('Search.Prg');
	public $presetVars = array(
		array('field' => 'title', 'type' => 'value'),
	);
	
	function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->paginate());
	}
	
	function find() {
		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Post->parseCriteria($this->passedArgs);
		$this->set('posts', $this->paginate());
    }
}

ビュー

index.ctp に検索フォームを設置します。

> index.ctp

echo $this->Form->create('Post', array(
    'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->label('title');
echo $form->text('title');
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();

この index.ctp を複製して、検索結果を表示するテンプレート find.ctp を作成します。

これが基本となります。

複数フィールドの絞り込み検索

タイトル(Post.title フィールド)と本文(Post.body フィールド)による絞り込み検索

検索フォームを追加します。

モデル

> post.php

class Post extends AppModel {
	public $actsAs = array('Search.Searchable');
	public $belongsTo = array('User');
	public $filterArgs = array(
		array('name' => 'title', 'type' => 'like'),
		array('body' => 'title', 'type' => 'like'),
	);
}

コントローラ

> posts_controller.php

class PostsController extends AppController {
	public $components = array('Search.Prg');
	public $presetVars = array(
		array('field' => 'title', 'type' => 'value'),
		array('field' => 'body', 'type' => 'value'),
	);
	
	function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->paginate());
	}
	
	function find() {
		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Post->parseCriteria($this->passedArgs);
		$this->set('posts', $this->paginate());
    }
}

ビュー

> index.ctp, find.ctp

echo $this->Form->create('Post', array(
    'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->label('title');
echo $form->text('title');
echo $form->label('body');
echo $form->text('body');
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();

アソシエーションテーブルのフィールドの検索

belongsTo の関係にある User モデルの username フィールドを検索。

モデルの検索条件で field パラメーターを指定します。他は同じです。

モデル

> post.php

class Post extends AppModel {
	public $actsAs = array('Search.Searchable');
	public $belongsTo = array('User');
	public $filterArgs = array(
		array('name' => 'username', 'type' => 'like', 'field' => 'User.username'),
	);
}

コントローラ

> posts_controller.php

class PostsController extends AppController {
	public $components = array('Search.Prg');
	public $presetVars = array(
		array('field' => 'username', 'type' => 'value'),
	);
	
	function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->paginate());
	}
	
	function find() {
		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Post->parseCriteria($this->passedArgs);
		$this->set('posts', $this->paginate());
    }
}

ビュー

> index.ctp, find.ctp

echo $this->Form->create('Post', array(
    'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->label('username');
echo $form->text('username');
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();

クエリー検索(OR検索)

1つの検索フォームから複数フィールドのOR検索

‘type’ => ‘query’ として、method パラメーターを追加します。

モデル

> post.php

class Post extends AppModel {
	public $actsAs = array('Search.Searchable');
	public $belongsTo = array('User');
	public $filterArgs = array(
		array('name' => 'filter', 'type' => 'query', 'method' => 'orConditions'),
	);
	
	public function orConditions($data = array()) {
		$filter = $data['filter'];
		$conditions = array(
			'OR' => array(
				$this->alias.'.title LIKE' => '%'.$filter.'%',
				$this->alias.'.body LIKE' => '%'.$filter.'%',
			));
		return $conditions;
    }
}

コントローラ

> posts_controller.php

class PostsController extends AppController {
	public $components = array('Search.Prg');
	public $presetVars = array(
		array('field' => 'filter', 'type' => 'value'),
	);
	
	function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->paginate());
	}
	
	function find() {
		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Post->parseCriteria($this->passedArgs);
		$this->set('posts', $this->paginate());
    }
}

ビュー

> index.ctp, find.ctp

echo $this->Form->create('Post', array(
    'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->label('filter');
echo $form->text('filter');
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();

アソシエーションテーブルのフィールドを含むクエリー検索

モデル

class Post extends AppModel {
	public $actsAs = array('Search.Searchable');
	public $belongsTo = array('User');
	public $filterArgs = array(
		array('name' => 'filter', 'type' => 'query', 'method' => 'orConditions'),
	);
	
	public function orConditions($data = array()) {
		$filter = $data['filter'];
		$conditions = array(
			'OR' => array(
				$this->alias.'.title LIKE' => '%'.$filter.'%',
				'User.username LIKE' => '%'.$filter.'%',
			));
		return $conditions;
    }
}

コントローラ

class PostsController extends AppController {
	public $components = array('Search.Prg');
	public $presetVars = array(
		array('field' => 'filter', 'type' => 'value'),
	);
	
	function index() {
		$this->Post->recursive = 0;
		$this->set('posts', $this->paginate());
	}
	
	function find() {
		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Post->parseCriteria($this->passedArgs);
		$this->set('posts', $this->paginate());
    }
}

ビュー

> index.ctp, find.ctp

echo $this->Form->create('Post', array(
    'url' => array_merge(array('action' => 'find'), $this->params['pass'])
));
echo $form->label('filter');
echo $form->text('filter');
echo $this->Form->submit(__('Search', true), array('div' => false));
echo $this->Form->end();

Comments

コメントを残す