Ваш код должен работать с if ( $this->User->validates() )
. Неправильное поведение, с которым у вас возникают проблемы, связано с тем, что Model::save()
сбрасывает элемент Model::validationErrors
, стирая пользовательскую ошибку проверки. Model::validates()
нет, поэтому ваша установка двойной проверки должна работать.
Например, следующие функции корректно работают в CakePHP 1.2.
Модель:
class User extends AppModel
{
var $validate = array(
'my_other_field' => array(
'rule' => 'notEmpty',
'message' => 'This field should not be empty.'
)
);
}
Контроллер:
class UsersController extends AppModel
{
function add()
{
if (! empty($this->data)) {
$this->User->set( $this->data );
if ( 'foo' != $this->data['User']['my_field'] ) {
$this->User->invalidate( 'my_field', 'Should be "foo".' );
}
if ( $this->User->validates() ) {
$this->flash('Form validated correctly.'); exit;
}
}
}
}
Вид:
<?php echo $form->create('User', array('action'=>'add')); ?>
<?php echo $form->input('User.my_field', array('value'=>'bar')); ?>
<?php echo $form->input('User.my_other_field', array('value'=>'')); ?>
<?php echo $form->end('Submit'); ?>
Отправлено как есть выше, ошибки проверки формы отображаются под обоими полями, одно из которых предоставлено логикой проверки контроллера, а другое - правилами проверки модели.
Большей проблемой, конечно, является запутывание ролей MVC, поскольку контроллер обрабатывает некоторые данные. Вы можете рассмотреть что-то вроде этого:
Контроллер:
class UsersController extends AppController
{
function add()
{
if (! empty($this->data)) {
$captcha = $this->Session->read('CAPTCHA_CODE');
$this->User->setCaptchaCheck( $captcha );
if ( $this->User->save( $this->data, array('validate'=>true))) {
$this->Session->setFlash('Success');
$this->redirect('success',303,true);
}
}
}
}
Модель:
class User extends AppModel
{
var $captchaCheck = '';
var $validates = array(
'captcha' => array(
'matchesCheck' => array(
'rule' => array( 'matchesCaptchaCheck', 'captchaCheck' ), // second value of array should match class member-name above
'message' => "CAPTCHAs don't match."
)
)
);
function matchesCaptchaCheck( $data, $checkVar )
{
$data = reset(array_values($data)); // I don't need to know the field name now.
return low($data) == low($this->{$checkVar});
}
function setCaptchaCheck( $captcha )
{
$this->captchaCheck = $captcha;
}
}
Теперь ваш контроллер блаженно не знает о том, как ваша модель проверяет свои данные, и даже о том, как эти данные структурированы; и ваша проверка формы все происходит в модели.
Надеюсь, это поможет.