5

I have given validation in model. Also, I have given some validation in controller for checking the captcha code. After that, the application is not displaying the model validation errors. If I comment the controller code, model validation is working fine and displaying the errors. Both not working..

Model code (sample)

class User extends AppModel {

var $name = 'User';

var $validate = array(
    'username' => 'notempty',
    'firstname' => 'notempty'
    );

}

Controller code

if (!empty($this->data)) {

$this->User->set($this->data);
$this->User->create();
$captcha = $this->Session->read('CAPTCHA_CODE');

if (strtolower($captcha) != strtolower($this->data['User']['captcha']))
{
    $this->User->invalidate('captcha', __('Sorry, your entry did not match', true));
}

if ($this->User->save($this->data, array('validate' => 'only')))
{
    if ($this->User->save($this->data, array('validate' => 'false'))) {
        $this->Session->setFlash(__('Registered successfully', true));
        $this->redirect('success');
    }
}else {
    $this->Session->setFlash(__('Please, try again.', true));
}

}

I have replaced the if ($this->User->save($this->data, array('validate' => 'only'))) line with if ($this->User->validates()), then also it is not working.

please help

1 Answer 1

11

Your code should work with if ( $this->User->validates() ). The incorrect behaviour you're having trouble with is because Model::save() resets the Model::validationErrors member, obliterating your custom validation error. Model::validates() doesn't, so your dual-validation setup should work.

For example, the following functions correctly, under CakePHP 1.2.

Model:

class User extends AppModel
{
    var $validate = array(
        'my_other_field' => array(
            'rule' => 'notEmpty',
            'message' => 'This field should not be empty.'
        )
    );
}

Controller:

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;
            }
        }
    }
}

View:

<?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'); ?> 

Submitted as-is above, form validation errors appear below both fields, one provided from the controller's validation logic, the other from the model's validation rules.

The larger issue, of course, is muddying the MVC roles by having the controller handling some data validation. You might want to consider something like this:

Controller:

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);
            }
        }
    }
}

Model:

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;
    }
}

Now your controller is blissfully ignorant of how your model validates its data, and even of how the data is structured; and your form validation all occurs in the model.

Hope this helps.

Sign up to request clarification or add additional context in comments.

2 Comments

Speaking of MVC, the Model should not have a captcha field. UserModel should not be aware of "captcha". Up to now, I am unable to find a suitable, logical solution for that problem.
@hongster, this is a great point. I am presently having an issue "validating" whether a new_password field matches a confirm_password field. However putting this logic in the Model wouldn't make sense. In regards to password you would really only be validating against your password rules. Thanks for setting me straight.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.