Posts tagged cakephp1.2

CakePHP1.2 バリデーションのルール

2

CakePHP1.2 のバリデーションのメモです。
詳しくは cake/libs/validation.php を見ると分かりやすいです。

半角英数字のみ

alphaNumeric

var $validate = array('field' => array('rule' => array('alphaNumeric')));

文字列の長さ

between

var $validate = array('field' => array('rule' => array('between', 6, 8)));
半角で6文字以上8文字以内

文字列が空

blank

var $validate = array('field' => array('rule' => array('blank')));

クレジットカード番号

cc

var $validate = array('field' => array('rule' => array('cc')));

比較

comparison

var $validate = array('field' => array('rule' => array('comparison', '>', 10)));
‘==’, ‘!=’, ‘< =’, など使用できる

正規表現

custom

var $validate = array('field' => array('rule' => array('custom', '/^[0-9]{3}\-[0-9]{4}$/')));
例として NNN-NNNN 形式の郵便番号のバリデーション

日付

date

var $validate = array('field' => array('rule' => array('date', 'ymd')));
‘dmy’, ‘mdy’, ‘ymd’, ‘dMy’, ‘Mdy’, ‘My’, ‘my’ が使用可

小数点の桁数チェック

decimal

var $validate = array('field' => array('rule' => array('decimal', 2)));

var $validate = array('field' => array('rule' => array('decimal', null, '/^[0-9]{2}\.[0-9]{2}$/')));
正規表現を指定してチェックすることも可。

メールアドレス

email

var $validate = array('field' => array('rule' => array('email')));

=== での比較

equalTo

var $validate = array('field' => array('rule' => array('equalTo', 'hoge')));
型も含めて等しいかチェック

拡張子

extension

var $validate = array('field' => array('rule' => array('extension', array('gif', 'jpg')));
ファイルの拡張子をチェック。許可したい拡張子を配列で指定。デフォルトは array(‘gif’, ‘jpeg’, ‘png’, ‘jpg’)

IPアドレス

ip

var $validate = array('field' => array('rule' => array('ip')));

最小文字数

minLength

var $validate = array('field' => array('rule' => array('minLength', 6)));

最大文字数

maxLength

var $validate = array('field' => array('rule' => array('maxLength', 12)));

数字

numeric

var $validate = array('field' => array('rule' => array('numeric')));

数字の範囲チェック

range

var $validate = array('field' => array('rule' => array('range', 0, 100)));
注意点は指定した数字は含まれない
上の例では 1?99 までが true

var $validate = array('field' => array('rule' => array('range')));
とすると有限数かどうかのチェック

URL

url

var $validate = array('field' => array('rule' => array('url')));

CakePHP1.2 モデルの generateList は非推奨メソッドなので find(’list’) を使用する

3

CakePHP で select タグを作成する際に CakePHP1.1 ではモデルの generateList メソッドを使用しましたが、このメソッドは CakePHP1.2 では非推奨メソッドになっているようです。その代わりに find メソッドを使用します。

$this->Model->generateList();
と書く代わりに
$this->Model->find('list');
と書きます。

find メソッドのこの書き方は他に

find(‘count’)
レコード数を取得する。COUNT(*) の SQL を実行する
find(‘first’)
最初のレコードを取得する。 LIMIT 1 で SQL を実行する
find(‘all’)
全てのレコードを取得する。findAll と同等。
findAll は内部で find(‘all’) を実行している。

などがあります。

CakePHP1.2 Form ヘルパーで日付のフォームを作る

1

CakePHP1.2 の Form ヘルパーを使用して日付のフォームを作成したときのメモです。

$attr = array('minYear' => 2000, 'maxYear' => date('Y'), 'separator' => ' / ');
echo $form->dateTime('Model/field', 'YMD', 'NONE', date('Y-m-d'), $attr);

とすると下のような日付を選択するフォームができます。

Form Helper Date

第2引数の ‘YMD’ で年月日の並び順を指定します。日付を表示しない場合は ‘NONE’ を指定します。

NONE
非表示
YMD
年月日の順に表示
DMY
日月年の順に表示
MDY
月日年の順に表示

第3引数で時間表示の指定をします。

NONE
非表示
12
時間を12時間表示
24
時間を24時間表示

第4引数でデフォルトの日時を指定します。

第5引数で属性を指定します。

separator
日付の select タグの間に表示する文字
minYear
開始する年
maxYear
終了する年
interval
分を何分刻みで表示するか

CakePHP1.2 文字コードを EUC-JP に設定する

1

現在開発しているシステムが文字コードを EUC-JP で制作しなければいけないのですが、今まで CakePHP は UTF-8 でしか制作したことがなく、設定方法などメモしておきます。開発に使用しているのは CakePHP1.2 です。

データベースの文字コード

app/config/database.php

var $default = array(
    'driver' => 'mysql',
    'persistent' => false,
    'host' => 'localhost',
    'port' => '',
    'login' => 'user',
    'password' => 'password',
    'database' => 'database_name',
    'schema' => '',
    'prefix' => '',
    'encoding' => 'ujis'
);

EUC のときは encoding に ujis と設定します。
ちなみに
Shift-JIS のときは sjis
UTF-8 のときは utf8
とします。
これは MySQL の SET NAMES でそのまま使用されるためです。

システムの文字コード

CakePHP1.2 では下記のように設定します。
app/config/core.php
Configure::write('App.encoding', 'euc-jp');

CakePHP 1.1 の方法はちょっとコードを調べたのですが、 core.php などにも特に設定するところがなく分かりませんでした。分かる方いらっしゃったら教えてください。

CakePHP1.2 のバリデーション

12

CakePHP 1.2 を使用してフォームを作成してバリデーションを使用したメモです。

下記サイトを参考にさせていただきました。
cakePHP 1.2のバリデーションを理解する – cakephp – クロアチアで働くプログラマー日記

例としてメールアドレスを2回入力させるフォームを考えて見ます。
バリデーションルールとして

  • 必須項目
  • メールアドレスとして正しい
  • メールアドレスがユニーク
  • 2回入力したメールアドレスが一致する

モデルにバリデーションを定義する

var $validate = array(
    'email' => array(
        'unique' => array(
    	    'rule' => array('checkUnique', 'email'),
    	    'message' => 'メールアドレスは既に登録されています'
    	),
        'rule1' => array(
       	    'rule' => array('email'),
       	    'message'=>'メールアドレスが正しくありません'
      	 ),
        'required' => array(
       	    'rule'=>VALID_NOT_EMPTY ,
       	    'message' => '必須項目です'
       	),
    ),
    'email_confirm' => array(
        'rule1' => array(
    	    'rule'=> array('checkCompare'),
    	    'message'=>'一致しません'
    	),
    ),
);

私はエラーメッセージをバリデーション定義にまとめておきたいので、上記のように各ルールに
'message' => 'エラーメッセージ'
として定義しています。
ここで定義しておけば、後でビューに書くフォームヘルパーでフォームを出力するときに引っかかったエラーを自動的に出力することができます。

また、自分でバリデーション関数を作成してチェックすることもできます。それが checkUnique と checkCompare です。

メールのユニークチェックは参考サイトを参考にさせていただきました。

function checkUnique($field){
    foreach( $field as $key => $value ){
        $this->recursive = -1;
        $found = $this->find(array("{$this->name}.$key" => $value));
        return !$found;
    }
}

次にメールアドレスを2回入れたものが一致するかのチェックです。
これはパスワードなどでもたまに使用するので汎用性を持たせてあります。
例えばメールアドレスのフィールド名が email の場合、確認用のフィールド名は ‘_confirm’を付けて email_confirm としておけばこの2つが一致するかチェックします。

function checkCompare($field) {
    foreach( $field as $key => $value ){
        if (preg_match('/^(.+)_confirm$/', $key, $regs)) {
            return $this->data[$this->name][$regs[1]] == $this->data[$this->name][$key];
        }
    }
}

ビューでフォームを設定

<?php echo $form->input('User/email', array('type'=>'text')); ?>
<?php echo $form->input('User/email_confirm', array('type'=>'text')); ?>

このように書いておけばバリデーションエラーがある場合は、モデルのバリデーションに定義したエラーメッセージを自動的に出力してくれます。

ちなみに上記のように書くと input タグの前に email などのフィールド名が出力されます。これを消したい場合は
<?php echo $form->input('User/email', array('type'=>'text', 'label'=>'')); ?>
と書くと表示されなくなります。

追記:
コメントで教えていただきました。label=>” だと表示されないが、label タグは残るので
<?php echo $form->input('User/email', array('type'=>'text', 'label'=>false)); ?>
とするとラベルタグも出力されなくなります。

コントローラでバリデーションチェック

以下のようになります。

function action() {
    if ($this->data) {
        if ($this->User->create($this->data) && $this->User->validates()) {
	    // バリデーションOK
	}
    }
}

他にもいろいろフォーム気がついた点があったのでそれはまた後でまとめます。

CakePHP1.2 バッチ処理

2

CakePHP1.2 にシェル機能というのがあるのを知りました。下記エントリでメールからの処理を実際に行う方法が紹介されています。
メール受信からのシェル機能実行 – Writing Some Code

ちょうど CakePHP1.2で開発中のシステムで cron でのバッチ処理があるのでそれに応用してみたときのメモです。

バッチ処理で実行させるシェル機能を作成

今回は test という名前のシェル名にします。
app/vendors/shells/test.php を作成します。

< ?php
class TestShell extends Shell {

    var $uses = array('Model');

    function actionName(){
        /* 実際の処理を書きます */
        /* $this->uses に追加したモデルが使用できます */
        $lists = $this->Model->findAll();
    }
}
?>

シェルスクリプト

下記のようなシェルスクリプトを作成して cron から実行させます。

#!/bin/sh
cd /path/to/app
../cake/console/cake test actionName

シェルスクリプトなしで直接 cake を実行する方法もある

cake を実行するときにカレントディレクトリが app でないとだめなのですが、
-app /path/to/app
のように -app オプションで実行時に app のパスを指定することもできます。
その場合は下記のようになります。
/path/to/cake/console/cake test actionName -app /path/to/app
これを直接 cron から実行させればシェルスクリプトなしでも実行できます。

その他

vendors/shells 内のファイルですが、ファイル名が hoge_foo.php だった場合、クラス名は HogeFooShell ですが、実行するときは
cake/console/cake hoge_foo actionName
となるようです。

CakePHP1.2 モデルのビヘイビアを動的に切り替える

0

CakePHP 1.2 から追加されたビヘイビアが動的に追加、削除できるようになるようです。
Attaching and detaching model behaviors on-the-fly – cakebaker

以前、CakePHP メール送信許可フラグによってメールを一斉送信するメールビヘイビア を書いたときに初めてビヘイビアというのを使ったのですが、ビヘイビアというのはうまく使えばかなり便利かなと思いました。

モデルに
var $actsAs = array('BehaviorName');
と書くことにより使えるようになるのですが、現在開発中の CakePHP1.2 でビヘイビアがモデルに attach , detach できるようになるようです。

ダウンロードできる最新の CakePHP 1.2.0.6311-beta にはまだ入っていませんが、以下より model.php のソースを手に入れて
cake/libs/model/model.php
に入れることによって試すことができます。
model.php のソース

モデルにビヘイビアをアタッチ、デタッチするのは以下のようになります。

$this->Model->attach('BehaviorName');
$this->Model->dettach('BehaviorName');

CakePHP HTML ヘルパーで出力されるタグを変更する方法

2

ヘルパーで出力されるタグを変更する方法です。

やりたいこと

ビューで
< ?php echo $html->link('Love CakePHP', 'http://www.cakephp.org'); ?>
と書くと
<div class="link"><a href="http://www.cakephp.org" >Love CakePHP</a></div>
と div タグで囲んで表示するようにしたい。

概要

app/config 内に変更したいタグを定義してヘルパーの親クラス(AppHelper) で定義したタグを読み込むという方法です。
CakePHP1.1 と 1.2 で少し方法が違います。

CakePHP1.1

app/config に tags.ini.php というファイルを作成しここにタグを定義すると自動的に反映されます。
app/config/tags.ini.php
link = <div class="link"><a href="%s" %s>%s</a></div>

CakePHP1.2

app/config/tags.php

< ?php
$tags = array(
    'link' => '<div class="link"><a href="%s" %s>%s</a></div>'
);
?>

app/app_helper.php

< ?php
class AppHelper extends Helper {
    function __construct() {
        parent::__construct();
        $this->loadConfig();
    }
}
?>

CakePHP 1.2 の AppHelper::loadConfig は以下のようになっていてデフォルトでは app/config/tags.php を読み込み $this->tags にマージします。

function loadConfig($name = 'tags') {
    if (file_exists(APP . 'config' . DS . $name .'.php')) {
        require(APP . 'config' . DS . $name .'.php');
        if (isset($tags)) {
            $this->tags = array_merge($this->tags, $tags);
        }
    }
    return $this->tags;
}

AppHelper のコンストラクタで
$this->loadConfig("hoge.php");
とすれば hoge.php のように任意のファイルを読み込んでマージすることができます。

HTML ヘルパーが使用するタグは cake/libs/view/helpers/html.php で $tags として定義されています。
この中のフォーム関連のタグは Form ヘルパーでも使用していますので、上記の方法で Formヘルパーで使用するタグも変更できます。

参考URL
Overriding specific HTML tags before using helper methods | The Bakery, Everything CakePHP : Articles

CakePHP 1.2 の deleteAll

1

CakePHP 1.2 の saveAll その1
CakePHP 1.2 の saveAll その2
のエントリーを書いているときに deleteAll というメソッドがあり気になったので調べてみました。

CakePHP 1.1 で開発時に delete するときに ID を指定するしか方法がなく、ある条件でまとめて削除したいときなどは findAll してからループで delete していました。このときも条件を指定して削除する方法がないかとソースを調べたのですがありませんでした。

使い方は非常に簡単です。findAll のように条件を指定して deleteAll を実行するだけです。

$conditions = array('User.name'=>'suzuki');
if ($this->User->deleteAll($conditions)) {
    $this->Session->setFlash('削除しました');
} else {
    $this->Session->setFlash('削除に失敗しました');
}

実行される SQL は以下のような感じです。

SELECT `User`.`id` FROM `users` AS `User` WHERE `User`.`name` = 'suzuki'
DELETE `User` FROM `users` AS `User` WHERE `User`.`id` IN (8, 10)

SELECT で条件に合う ID を抽出して WHERE IN で DELETE しています。
ただし CakePHP1.2 の削除ですが、MySQL 4.0 では SQL の DELETE 文でエラーになってしまいます。
MySQL 5.0 ではエラーにならずに削除できました。エラーになる原因は “DELETE” の後ろにテーブルのエイリアス名があるためです。

これは “cakephp1.2でのPostgreSQLエラー。” フォーラム – CakePHP Users in Japan でもあるように既に修正されているようですが、昨日 CakePHP のサイトからダウンロードした CakePHP 1.2.0.6311 beta ではまだ修正されていないようです。

CakePHP 1.2 の saveAll その2

3

CakePHP 1.2 の saveAll その1 では同一モデルへの複数レコードを saveAll で保存しました。今回はアソシエーションのモデルのデータを saveAll で保存する方法です。

アソシエーションのモデルのデータを保存

モデル
user.php

< ?php
class User extends AppModel {
    var $name = 'User';
    var $hasMany = array('Comment');
}
?>

comment.php

< ?php
class Comment extends AppModel {
    var $name = 'Comment';
    var $belongsTo = array('User');
}
?>

コントローラ
users_controller.php

function add() {
    if (!empty($this->data)) {
        $this->cleanUpFields();
        $this->User->create();
        if ($this->User->saveAll($this->data)===false) {
            $this->Session->setFlash('保存に失敗しました);
        } else {
            $this->Session->setFlash('保存しました');
        }
        $this->redirect(array('action'=>'index'), null, true);
    }
}

ビュー
users/add.ctp

< ?php echo $form->create('User');?>
< ?php echo $form->input('User.name');?>
< ?php echo $form->input('Comment.body'); ?>
< ?php echo $form->end('Submit');?>

CakePHP 1.2 の saveAll その1 の同一モデルへの複数レコードの保存よりも使い道は多いのではないかと思います。

追記
このエントリーは CakePHP 1.2.0.6311 beta で検証しています。

Go to Top