Search Plugin for CakePHP をとりあえず導入してみる
さいしょに
以前から検索機能が欲しかったので触ってみよう、触ってみようと思ってた「Search Plugin」です。
思ったより参考記事が少なく途中挫折しかかりましたが、無事導入も終わったので必要最低限の内容を記事にしてみます。
今回使うビヘイビア: CakeDC/search
あと、CakePHPのRootフォルダは「caketest」とします。
完成図
# 店舗名検索(フリガナ可)、公開設定の絞り込みとページネ-ションを使えるようにします。
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(); ?> <?php echo $this->Paginator->numbers(); ?> <?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);」にしないと動きませんでした。