概要
- ビューの入力欄の maxlength とモデルのバリデートの maxLength の値を1箇所で管理したい。
- 下のサンプルだと"100"という値をビューで1回、モデルで1回記述している。
View
<?= $this->Form->input('Post.name', array(
'type' => 'text',
'maxlength' => 100,
);?>
Model
public $validate = array(
'name' => array(
'rule' => array('maxLength', 100),
'message' => '%s 字以内で入力して下さい。',
),
);
ソースコード
上記の"100"の定義を1箇所にまとめるサンプルを作成しました。
https://github.com/gold1/CakePHP-maxlength-sample
以下、解説していきます。
まずは、カラム名と文字列長さの配列定義をモデルに作成します。
app/Model/It.php
protected static $maxLengthJp = array(
'name' => 30,
'note' => 100,
);
配列定義にアクセス/判定を行う関数をAppModelに追加します。
app/Model/AppModel.php
public static function isMaxLengthJp($column)
public static function getMaxLengthJp($column)
文字列長さのチェック関数(ruleMaxLengthJp)を独自実装します。
app/Model/AppModel.php
public function ruleMaxLengthJp($data, $length) {
$encoding = Configure::read('App.encoding');
$value = array_shift($data);
return (mb_strlen($value, $encoding) <= $length);
}
上記のチェック関数を実行する前にバリデートルールを変更。文字列の長さ定義を設定しています。
app/Model/AppModel.php
public function modifyValidateRure() {
// ...
if ($rule == 'ruleMaxLengthJp') {
// ルール変更をおこなって文字数を引数に設定する
$length = static::getMaxLengthJp($column);
$this->validate[$column][$number]['rule'] = array($rule, $length);
}
これで validate:rule 部分の記述を移動できました。
app/Model/It.php
public $validate = array(
'name' => array(
'ruleMaxLengthJp' => array(
'rule' => 'ruleMaxLengthJp',
'required' => true,
'allowEmpty' => false,
'last' => true,
'message' => 'name は %s文字までです。',
),
),
次に FormHelper を継承した Form2Helper を作成して input() を上書きします。maxlength の値をここで設定します。
app/View/Helper/Form2Helper.php
public function input($fieldName, $options = array()) {
list($model_name, $column_name) = $this->getModelAndColumnByFieldName($fieldName);
if ($options['type'] == 'text' ||
$options['type'] == 'textarea') {
if (class_exists($model_name) &&
$model_name::isMaxLengthJp($column_name)) {
$options = array_merge(
array('maxlength' => $model_name::getMaxLengthJp($column_name)),
$options
);
}
}
return parent::input($fieldName, $options);
}
AppController でこのヘルパーを指定する必要があります。
app/Controller/AppController.php
public $helpers = array(
'Form' => array(
'className' => 'Form2',
),
);
これでビュー側の定義を移動できました。
app/View/It/form.php
<?= $this->Form->input('Post.name', array(
'type' => 'text',
);?>
最後に
- プラグイン形式でまとめたかったけど、方法が思いつきませんでした。