CakePHP Behaviorでバリデーション周りの効率化を図る 応用編
前回紹介したBasicValidationBehaviorを使って、動的にバリデーションを切り替える方法を紹介します。
共通のモデルを複数のフォームで利用している場合にバリデーションの定義を動的に変更したい場合などに有効です。
例1:新規登録時と編集時でバリデーションの登録項目を変更する
対応1)loadValidate()メソッドに引数を追加し、条件によって分岐させる
[モデル内の処理]
-
function loadValidate($action = 'add') {
-
'name' => 'required | maxLen[50]',
-
'email' => 'required | email | isUnique | maxLen[200]',
-
'password' => 'required | single | maxLen[20] | minLen[6]',
-
're_password' => 'required | confirm[password]',
-
'sex' => 'required | numeric | maxLen[1]',
-
'birthday' => 'required | ymd',
-
'tel' => 'required | phone | maxLen[13]',
-
'zip' => 'required | zip | maxLen[8]',
-
'pref' => 'required | maxLen[12]',
-
'addr1' => 'required | maxLen[200]',
-
'addr2' => 'maxLen[200]',
-
);
-
// 新規登録時以外はパスワード関連の項目を無効にする
-
if($action !== 'add'){
-
}
-
$this->setValidate($valid);
-
}
対応2)コントローラーでモデルのvalidate()やsave()前にloadValidate()を明示的に実行する
[コントローラー内の処理]
-
function add(){
-
// 処理を省略
-
-
$this->TestUser->set($this->data);
-
// バリデーションを設定
-
$this->TestUser->loadValidate('add');
-
if($this->TestUser->validates()) {
-
-
// 処理を省略
-
}
-
-
function edit($id = null){
-
// 処理を省略
-
-
$this->TestUser->id = $id;
-
$this->TestUser->set($this->data);
-
// バリデーションを設定
-
$this->TestUser->loadValidate('edit');
-
if($this->TestUser->validates()) {
-
-
// 処理を省略
-
}
CakePHP Behaviorでバリデーション周りの効率化を図る
CakePHPでバリデーションを使う際、標準(CakePHP1.2)のままでも十分開発はできますが、大きめのプロジェクトや複数のプロジェクトでも汎用的かつ効率的に使えるようにできないかと検討しました。
バリデーション改善の目的
- エラーメッセージを日本語化し共通化・デフォルト化したい
- 独自バリデーションメソッドを共通化したい
- ルール配列を簡単に記述したい(項目が多いとソースが長くなり過ぎて見通しがよくない)
- バリデーションの前に自動で整形処理をしたい(半角英数変換やカタカナ変換など)
実装にあたって
バリデーションメソッドの共通化については、
cakephperさんの日記:よく使う独自バリデーションルールをプラグインのbehaviorにまとめる
に記載してありますように、プラグインのbehaviorで管理するほうが良いと思いますが、今回は弊社で過去に実装した通常のbehavior(BasicValidationBehaviorとします)を使った方法を紹介します。
CakePHP Formヘルパの拡張 その2
3項目の電話番号入力フィールド
$form->textを拡張して3項目の電話番号入力フィールドを生成
前回に続いて、Formヘルパの拡張の第二弾です。
入力欄としてよくあるものとしては、電話番号や郵便番号を分割された入力フィールドで入力させるケースがあります。
入力フォームはモデル(テーブル)と連携するケースが多いですが、テーブルのカラムが1つなのに入力フォームは分割しなければならない場合などは、少々面倒なことを行う必要があります。
この煩わしさを回避する為に、カラムは1つでも入力欄は3つに自動的に分割されるようにに拡張する方法を検討しました。
結論から言えば、ヘルパだけの拡張では入力欄を分割するところまではできましたが、DBに格納する際に自動的に分割した値を結合することができませんでした。
(イマイチな)解決案として、AppModel内に処理を追加することでDB格納時の自動結合化を行っています。
動作はこちらから確認できます。
Read more
CakePHP Formヘルパの拡張 その1
日本語日付選択プルダウン
$form->datetimeを拡張して日本語の日付選択プルダウンを生成
CakePHP1.2のFormHelperには日付をプルダウンメニューで選択する機能があります。
生年月日の入力などに重宝しますが、日付の書式が英語なので日本の日付形式に変更する必要があります。
そこで、Formヘルパを拡張してExformヘルパクラスを生成し、独自メソッド内で日本語化対応を実施します。
動作はこちらから確認できます。
Read more
CakePHP HABTMモデルの検索
HABTMで関連付けされたテーブルを検索条件に加えたい場合、一回のfindメソッドで取得しようとすると、joinの設定やグループ化で面倒な実装が必要になってきます。
データ量にもよりますが、
1)関連テーブルを先に検索し、ID配列を取得
2)ID配列を検索条件に追加
としたほうが簡単に実装できるケースが多そうです。
Read more
CakePHP コントローラーのアクションをコンポーネントにまとめる
本業のほうが忙しく久々の更新になってしまいましたが小ネタです。
Cakeを使っていると最初はbakeやscaffoldを利用する機会がありますが、序々に利用頻度が減ってきました。(現在では殆ど使っていません)
理由としては、社内での共通のルールであったり、プロジェクト毎の特性を反映した雛型から複製して作成したほうが効率的になってきたということが大きいと思います。
ただ、bakeでの自動生成や複製方式だと初回は良いのですが、大規模なものになってくると、同様のソースが点在し一括での改修などが面倒なことになってきます。
ということで、明らかに同様の処理はscaffold風にコンポーネント化することにしました。
※コンポーネントからコントローラーを制御する場合は、ロジックが分散すると見通しが悪くなりますので、ロジック全体を委譲できる場合に利用することをお勧めします。
Read more
CakePHP zip圧縮コンポーネント
CodeIgniterの標準ライブラリにはZip圧縮クラスがあり、簡単に以下のような機能を実装することができます。
・Zipアーカイブを作成し、サーバーに保存やダウンロードを行う
・サーバーのファイルやディレクトリをZipに追加
・動的にテキストデータをZipに追加
このクラスをCakePHPのコンポーネントクラスとして利用できるように少々改良しました。
Read more
DAY10: AJAXでデータ操作
質問の投稿
新しい質問の投稿をAJAXを使ったフォームで実装していきます。
ログインフォームをAJAXで実装しているので基本は同じです。
symfony1.0との違いはやはりsfFormを利用した実装です。
DAY9: ローカルの改善
これまでのおさらい
symfonyで簡単なよくあるAJAXを実装するための関数や機能が用意されているのがわかりました。
また、外部ライブラリがコアのプラグインとして提供されるようになったということがわかりました。
9日目はテキストエリアのMarkdown対応と、ルーティングの変更です。
CakePHP1.2 Behaviorでモデルのメソッドキャッシュを行う
CakePHP1.2から新たにBehavior(振る舞い)クラスが実装され、モデルに共通の処理を定義することが可能になりました。
今回はBehaviorを使ってモデルの各メソッドの結果を自動的にキャッシュするクラス(CacheBehavior)を検討してみました。
CakePHPでは標準でビューキャッシュをサポートしていますが、Cacheクラスを利用することで簡単にキャッシュ機能を組み込むことができます。
