Home > Tags > validate
validate
[cakephp1.2]CakePHP1.2.0.7296 RC2用DRYなエラーメッセージ出力を一部修正しました。[validate]
以前のエントリー[cakephp1.2]CakePHP1.2.0.7296 RC2用DRYなエラーメッセージ出力。[validate]
で載せていた【app/models/app_model.php】内のinvalidFieldsファンクション内で
validate設定の”required”を考慮したコードになっていなかったので修正しました。
[cakephp1.2]CakePHP1.2.0.7296 RC2用DRYなエラーメッセージ出力。[validate]に修正済のコードを載せておきました。
- Comments: 0
- Trackbacks: 0
[cakephp1.2]CakePHP1.2.0.7296 RC2用DRYなエラーメッセージ出力。[validate]
※ 2008/10/22追記
【app/models/app_model.php】内のinvalidFieldsファンクション内でvalidate設定の”required”を考慮したコードになっていなかったので修正しました。適当なコード載っけてすみません。
以前にngtnさんのvalidationのメッセージ出力をDRYにしてみるっていうエントリーを見てから、CakePHP1.2ではずっとDRYなエラーメッセージ出力を使わせてもらってたんですが、CakePHPのバージョンを1.2.0.7296 RC2にすると動かなくなってしまいました。
で、動くようにしてみましたよ。偉そうにいうほどの修正量じゃありませんが・・・
修正したのは【app/app_model.php】のみです。全部載っけておきます。
< ?php config('messages'); class AppModel extends Model { var $db = null; function __construct() { parent::__construct(); $this->db =& ConnectionManager::getDataSource($this->useDbConfig); } function escape($data=null) { return $this->db->value($data); } //テーブル名のゲッタ function getTableName() { return $this->name; } //重複チェックのバリデート function checkDuplicate($data) { $cond = array(key($data) => '= '.current($data)); if(($id = $this->getID()) !== false){ $cond[$this->getTableName().'.id'] = '!= '.$id; } return ($this->findCount($cond) === 0) ? true : false; } /** * invalidFieldsメソッドのオーバーライド * * @param array $data Parameter usage is deprecated, set Model::$data instead * @return array Array of invalid fields * @access public */ function invalidFields($options = array()) { if (!$this->Behaviors->trigger($this, 'beforeValidate', array($options), array('break' => true, 'breakOn' => false)) || $this->beforeValidate($options) === false) { return $this->validationErrors; } if (!isset($this->validate) || empty($this->validate)) { return $this->validationErrors; } $data = $this->data; $methods = array_map('strtolower', get_class_methods($this)); $behaviorMethods = array_keys($this->Behaviors->methods()); if (isset($data[$this->alias])) { $data = $data[$this->alias]; } elseif (!is_array($data)) { $data = array(); } $Validation =& Validation::getInstance(); $this->exists(); foreach ($this->validate as $fieldName => $ruleSet) { if (!is_array($ruleSet) || (is_array($ruleSet) && isset($ruleSet['rule']))) { $ruleSet = array($ruleSet); } $default = array('allowEmpty' => null, 'required' => null, 'rule' => 'blank', 'last' => false, 'on' => null); foreach ($ruleSet as $index => $validator) { if (!is_array($validator)) { $validator = array('rule' => $validator); } $validator = array_merge($default, $validator); if (isset($validator['message'])) { $message = $validator['message']; } else { $message = __('This field cannot be left blank', true); } $messageParams = array(); if(isset($validator['message_params'])) { $messageParams = $validator['message_params']; } if (empty($validator['on']) || ($validator['on'] == 'create' && !$this->__exists) || ($validator['on'] == 'update' && $this->__exists)) { if ((!isset($data[$fieldName]) && $validator['required'] === true) || (isset($data[$fieldName]) && (empty($data[$fieldName]) && !is_numeric($data[$fieldName])) && $validator['allowEmpty'] === false)) { $this->invalidate($fieldName, $message, $messageParams); if ($validator['last']) { break; } } elseif (array_key_exists($fieldName, $data)) { if (empty($data[$fieldName]) && $data[$fieldName] != '0' && $validator['allowEmpty'] === true) { break; } if (is_array($validator['rule'])) { $rule = $validator['rule'][0]; unset($validator['rule'][0]); $ruleParams = array_merge(array($data[$fieldName]), array_values($validator['rule'])); $messageParams = array_values($validator['rule']); } else { $rule = $validator['rule']; $ruleParams = array($data[$fieldName]); $messageParams = array(); } if ( array_key_exists($rule, Messages::$error)) { $message = Messages::$error[$rule]; $validator['message'] = $message; } $valid = true; if (in_array(strtolower($rule), $methods)) { $ruleParams[] = array_diff_key($validator, $default); $ruleParams[0] = array($fieldName => $ruleParams[0]); $valid = $this->dispatchMethod($rule, $ruleParams); } elseif (in_array($rule, $behaviorMethods) || in_array(strtolower($rule), $behaviorMethods)) { $ruleParams[] = array_diff_key($validator, $default); $ruleParams[0] = array($fieldName => $ruleParams[0]); $valid = $this->Behaviors->dispatchMethod($this, $rule, $ruleParams); } elseif (method_exists($Validation, $rule)) { $valid = $Validation->dispatchMethod($rule, $ruleParams); } elseif (!is_array($validator['rule'])) { $valid = preg_match($rule, $data[$fieldName]); } if (!$valid) { if (!isset($validator['message'])) { if (is_string($index)) { $validator['message'] = $index; } else { $validator['message'] = ife(is_numeric($index) && count($ruleSet) > 1, ($index + 1), $message); } } $this->invalidate($fieldName, $validator['message'], $messageParams); if ($validator['last']) { break; } } } } } } return $this->validationErrors; } /** * invalidateのオーバーライド * * @param string $field The name of the field to invalidate * @param string $value Name of validation rule that was not met * @access public */ function invalidate($field, $value = null, $messageParams = array()) { if (!is_array($this->validationErrors)) { $this->validationErrors = array(); } if (empty($value)) { $value = true; } if (count($messageParams) > 0) { $value = vsprintf($value, $messageParams); } // 既にセットしてある場合は、区切り文字を挟んで連結する if (!empty($this->validationErrors[$field])) { $this->validationErrors[$field] .= Messages::$separator . $value; } else { $this->validationErrors[$field] = $value; } } } ?>
こんだけです。いちおう他のスクリプトも。
【app/config/messages.php】
< ?php class Messages { /** * メッセージの区切り文字 * * @var string */ static $separator = "<br />"; /** * validationルールに対応するエラーメッセージ * * @var array */ static $error = array( VALID_NOT_EMPTY => '必ず入力してください。', VALID_NUMBER => '半角数字を入力してください。', VALID_EMAIL => 'メールアドレス形式で入力してください。', VALID_YEAR => '年(1000~2999)を入力してください。', 'alphaNumeric' => '半角英数字を入力してください。', 'between' => '%1$d文字以上%2$d文字以内の半角数字を入力してください。', 'blank' => '空でなければなりません。', 'cc' => 'クレジットカード番号として正しくありません。', 'comparison' => '入力値%1$s%2$sを満たす値を入力してください。', 'custom' => '入力値が正しくありません。', 'date' => '日付形式(%1$s)で入力してください。', 'decimal' => '小数点第%1$d位までの半角数字を入力してください。', 'email' => 'メールアドレス形式で入力してください。', 'equalTo' => '入力値が"%1$s"と一致しません。', 'extension' => '拡張子が正しくありません。', 'file' => '', // 実装されていない 'ip' => 'IPアドレス形式で入力してください。', 'minLength' => '%1$d文字以上で入力してください', 'maxLength' => '%1$d文字以内で入力してください', 'money' => '入力値が正しくありません。',// 通貨? 'multiple' => '', // 実装されていない 'numeric' => '半角数字を入力してください。', 'phone' => '電話番号形式で入力してください。', 'postal' => '郵便番号形式で入力してください。', 'range' => '%1$dより大きく%2$dより小さい半角数字を入力してください。', 'ssn' => 'ソーシャルセキュリティナンバー形式で入力してください。', 'url' => 'URL形式で入力してください。', 'userDefined' => '入力値が正しくありません。', ); } ?>
【app/views/helpers/app_form.php】
< ?php class AppFormHelper extends FormHelper { /** * errorメソッドのオーバーライド * * @param string $field A field name, like "Modelname.fieldname", "Modelname/fieldname" is deprecated * @param string $text Error message * @param array $options Rendering options for <div /> wrapper tag * @return string If there are errors this method returns an error message, otherwise null. * @access public */ function error($field, $text = null, $options = array()) { $this->setEntity($field); $options = array_merge(array('wrap' => true, 'class' => 'error-message', 'escape' => false), $options); if ($error = $this->tagIsInvalid()) { if (is_array($text) && is_numeric($error) && $error > 0) { $error--; } if (is_array($text) && isset($text[$error])) { $text = $text[$error]; } elseif (is_array($text)) { $text = null; } if ($text != null) { $error = $text; } elseif (is_numeric($error)) { $error = sprintf(__('Error in field %s', true), Inflector::humanize($this->field())); } if ($options['escape']) { $error = h($error); unset($options['escape']); } $messages = explode(Messages::$separator, $error); $output = ''; foreach ( $messages as $message){ if ($options['wrap'] === true) { unset($options['wrap']); $output .= $this->output(sprintf($this->Html->tags['error'], $this->_parseAttributes($options), $message)); $options['wrap'] = true; } else { $output .= $message; } } return $output; } else { return null; } } } ?>
【app/controllers/app_controller.php】
<php class AppController extends Controller { var $helpers = array('Html', 'Form', 'AppForm'); } ?> </php>
以上です。使いかたはngtnさんの
validationのメッセージ出力をDRYにしてみるっていうエントリーを見てください。 Continue reading
- Comments: 0
- Trackbacks: 1
[cakephp]テーブル未使用モデルで$this->Model->create()するとエラー吐くよ。
Modelで
var $useTable = false;
という設定をして、
$this->Model->create($this->data);
をすると、
Warning (512): (Model::getColumnType) Unable to locate model field data. If you are using a model without a database table, try implementing schema() [CORE/cake/libs/model/model.php, line 959] Code | Context $column = "how_know" $cols = array() $cols = $this->schema(); if (empty($cols)) { trigger_error(__('(Model::getColumnType) Unable to locate model field data. If you are using a model without a database table, try implementing schema()', true), E_USER_WARNING); Model::getColumnType() - CORE/cake/libs/model/model.php, line 959 Model::deconstruct() - CORE/cake/libs/model/model.php, line 857 Model::set() - CORE/cake/libs/model/model.php, line 839 Model::create() - CORE/cake/libs/model/model.php, line 1014 PartnersController::regist() - APP/controllers/partners_controller.php, line 20 Dispatcher::_invoke() - CORE/cake/dispatcher.php, line 265 Dispatcher::dispatch() - CORE/cake/dispatcher.php, line 237 [main] - APP/webroot/index.php, line 84
というエラーを吐いてきたんですよ。
エラー見ると、
$this->data["Model"]["how_know"]
という要素に格納されている値に問題あるみたいですね。
ちなみに、セレクトボックスと選択したした値(配列)が格納されています。
で、色々と調べてみると、Tableを使ってはいなくても、TableのSchema情報を定義しておけ、と。
つーことでModelを再設定します。
var $useTable = false; var $_schema = array("how_know"=>array("type"=>"string"));
これでエラーを吐かなくなりました。
- Comments: 0
- Trackbacks: 0
[cakephp1.2]validate使用時の注意。[validate]
cakephp1.1の時のように、
$this->yourmodel->validates($this->data);
とすると、cakephp1.2では
(Model::validates) Parameter usage is deprecated, set the $data property instead Warning (512): [CORE/cake/libs/model/model.php, line 1647]
とWarningを吐きます。1.2では下記のようにしましょう。
if ($this->YourModel->create($this->data) && $this->YourModel->validates()) { // validation ok } else { // validation not ok }
また、新規登録時のvalidateルールを下記の様に設定するとする。
var $validate = array( "name"=>array( array("rule"=>VALID_NOT_EMPTY) ), "kana"=>array( array("rule"=>VALID_NOT_EMPTY) ) )
でも、データ更新時にはvaidateルールから
「kana」のvalidateルールを除きたい場合は、
unset($this->YourModel->validate['kana']);
と書くよ。
- Comments: 1
- Trackbacks: 0
Home > Tags > validate