なんかできたよー。

Web系Tipsを適当につづるBlog.

Search Plugin for CakePHP をとりあえず導入してみる

f:id:tuki0918:20130607143926p:plain

さいしょに

以前から検索機能が欲しかったので触ってみよう、触ってみようと思ってた「Search Plugin」です。

思ったより参考記事が少なく途中挫折しかかりましたが、無事導入も終わったので必要最低限の内容を記事にしてみます。

今回使うビヘイビア: CakeDC/search

あと、CakePHPのRootフォルダは「caketest」とします。

完成図

f:id:tuki0918:20130602233123p:plain

# 店舗名検索(フリガナ可)、公開設定の絞り込みとページネ-ションを使えるようにします。

DBの準備

CREATE TABLE IF NOT EXISTS `shops` (
  `id` int(8) unsigned zerofill NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `kana` varchar(255) NOT NULL,
  `display` int(1) NOT NULL DEFAULT '0',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=8 ;


INSERT INTO `shops` (`id`, `name`, `kana`, `display`) VALUES
(00000001, '串カツ山上', 'クシカツヤマウエ', 1),
(00000002, 'ステーキ・山本', 'ステーキ・ヤマモト', 1),
(00000003, '山下家', 'ヤマシタケ', 0),
(00000004, '未在', 'ミザイ', 0),
(00000005, '鳥串', 'トリクシ', 1),
(00000006, '利馬蹄', 'リバテイ', 0),
(00000007, 'すずき', 'スズキ', 1);

 

Search Pluginの導入

https://github.com/CakeDC/searchのZIPよりファイルをダウンロードして解凍後の「search-master」というフォルダを「Search」にリネームして
「app/Plugin/」にアップロードします。


「app/Config/bootstrap.php」の末尾に追加します。

CakePlugin::load('Search');

 

app/Model/Shop.php


# 「name と「kana」から同時にLIKE検索したい + バリデーション ある場合

<?php
class Shop extends AppModel {

	public $actsAs = array('Search.Searchable');

	public $filterArgs = array(
		'name' => array('type' => 'query', 'method' => 'orConditions'),
		'display' => array('type' => 'value'),
	);

	public function orConditions( $data = array() ) {
		$filter = $data['name'];
		$cond = array(
			'OR' => array(
				$this->alias . '.name LIKE' => '%' . $filter . '%',
				$this->alias . '.kana LIKE' => '%' . $filter . '%',
			),
		);
		return $cond;
	}

	public $validate = array(
		'name' => array(
			array(
				'rule' => 'notEmpty',
				'message' => '店舗名を入力して下さい',
			),
		),
	);

}

 

# 「name」の完全一致の場合

<?php
class Shop extends AppModel {

	public $actsAs = array('Search.Searchable');

	public $filterArgs = array(
		'name' => array('type' => 'value'),
		'display' => array('type' => 'value'),
	);

}

 

app/Controller/ShopsController.php

<?php
class ShopsController extends AppController {

	public $components = array('Search.Prg');

	public $presetVars = true;

	public $paginate = array();

	public function index() {

		$this->paginate = array(
			'limit' => 2,
		);

		$this->Prg->commonProcess();
		$this->paginate['conditions'] = $this->Shop->parseCriteria($this->passedArgs);

		$shopList = $this->paginate();
		$this->set(compact('shopList'));

	}

}

 
# passedArgs について参考:cakephp疑問点一覧 - Inquisitive!
 

app/View/Shops/index.ctp

<?php $dispaly = array( '0' => '非表示', '1' => '表示' ); ?>

<div class="section form_search">
	<h2>検索項目</h2>
	<?php echo $this->Form->create('Shop', array( 'novalidate' => true, 'url' => array_merge(array('action' => 'index'), $this->params['pass']) )); ?>
	<h3>店舗名</h3>
	<?php echo $this->Form->input('name', array('placeholder' => '例)店舗名を入力して下さい。 ※フリガナ可', 'label' => false)); ?>
	<h3>公開設定</h3>
	<?php echo $this->Form->select('display', $dispaly, array( 'empty' => 'すべて', 'label' => false )); ?>
	<?php echo $this->Form->submit('検索'); ?>
	<?php echo $this->Form->end(); ?>
</div>

<div class="section">
	<h2>店舗一覧</h2>
	<table>
		<tr>
			<th><?php echo $this->Paginator->sort('id', 'ID'); ?></th>
			<th><?php echo $this->Paginator->sort('name', '店舗名'); ?></th>
			<th><?php echo $this->Paginator->sort('display', '公開設定'); ?></th>
		</tr>

		<?php foreach($shopList as $shop): ?>

		<tr>
			<td><?php echo h($shop['Shop']['id']); ?></td>
			<td><?php echo h($shop['Shop']['name']); ?></td>
			<td><?php echo $dispaly[h($shop['Shop']['display'])]; ?></td>
		</tr>

		<?php endforeach; ?>

	</table>
</div>


<div class="paginateLinks">
	<?php echo $this->Paginator->prev(); ?>&nbsp;
	<?php echo $this->Paginator->numbers(); ?>&nbsp;
	<?php echo $this->Paginator->next(); ?>
</div>

<?php echo $this->Html->css('shop_index', null, array( 'inline' => false )); ?>

 
# name に validate で notEmpty 付いていた場合、入力必須となるので、「'novalidate' => true」で回避しています。
参考:CakePHP2.3からinputタグにhtml5のrequired属性がつくようになった - cakephperの日記(CakePHP, MongoDB)
 

app/webroot/css/shop_index.css

@charset "UTF-8";

body {
	font-family: "メイリオ","Meiryo","ヒラギノ角ゴ Pro W3","Hiragino Kaku Gothic Pro","MS ゴシック","Osaka",sans-serif;
	line-height: 1.8;
}

.section {
	margin-top: 30px;
}

.form_search {
	padding: 30px;
	background-color: #efefef;
	-webkit-border-radius: 8px;
	-moz-border-radius: 8px;
	border-radius: 8px;
}

.form_search form {
	margin: 0 auto;
	width: auto;
}

.form_search h2 {
	margin-bottom: 0;
	background-color: transparent;
}

.form_search h3,
.form_search .submit {
	margin-top: 20px;
	padding: 20px 0 0 0;
	border-top: 1px solid #ccc;
}

.form_search .submit input {
	width: 100px;
}

 

さいごに

解説無しでごめんなさい。

今回利用しているのはさくらVPSで上記内容で動きましたが、
別の「Search Plugin」のコードをロリポップサーバーで試した際「Configure::write('debug', 0);」にしないと動きませんでした。