Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

CakePHP 2.3 form not showing validation errors

I have been trying to debug this for about two days and have read every answer to this question on the internet... and still can't get it to work.

In my CakePHP app I have a user sign-up form, which uses a model called User and the Form helper. When validation fails, the form does not show any of the validation errors.

The $this->User->validationErrors array is properly populated before the view is rendered, according to debug(), and the fact that the model does not validate is detected by $this->User->save().

Here's my view:

<?php
echo $this->Form->create('User');
echo $this->Form->input('soton_username', array('label' => 'Email address', 'after' => '@soton.ac.uk'));
echo $this->Form->input('username', array('label' => 'Choose a username'));
echo $this->Form->input('password');
echo $this->Form->input('password_confirm', array('label' => 'Password (again)', 'type' => 'password'));
echo $this->Form->input('first_name');
echo $this->Form->input('last_name');
echo $this->Form->submit('Create account');
echo $this->Form->end();
?>

Here's my action:

public function create() {
    if($this->request->is('post')) {
        $this->User->set($this->request->data);

        $valid = true;
        $validationErrors = array();
        $password = $this->request->data('User.password');
        $password_confirm = $this->request->data('User.password_confirm');

        if(strlen($password) < 5) {
            $validationErrors['password'][] = 'Password must be at least 5 characters long';
            $valid = false;
        }

        if($password != $password_confirm) {
            $validationErrors['password_confirm'][] ='Passwords do not match';
            $valid = false;
        }

        $this->User->data['User']['email'] = $this->request->data('User.soton_username') . '@soton.ac.uk';

        $group = $this->Group->find('first', array('conditions' => array('default' => 1)));
        if($group) {
            $gid = $group['Group']['id'];
        } else {
            $gid = 1;
        }
        $this->User->data['User']['group_id'] = $gid;

        if($this->User->validates() && $valid) {
            $this->User->save();
            $this->Session->setFlash('<a href="/users/activate/' . $this->User->data['User']['activation_id'] . '">Activate</a>');
            return $this->redirect('/users/confirm_create');
        }

        $this->User->validationErrors = array_merge($this->User->validationErrors, $validationErrors);

        if(isset($this->User->validationErrors['email'])) {
            $this->User->validationErrors['soton_username'] = $this->User->validationErrors['email'];
        }

        //debug($this->request->validationErrors);exit;
        $this->Session->setFlash('There were errors with the form.');
    }
}

The soton_username and password_confirm fields are not actually part of the database, but still need to be validated.

My User model does have a $validate variable which Form does recognise as it inserts required="required" in the right places.

Any help would be appreciated.

like image 260
james the seventh Avatar asked Jul 23 '13 00:07

james the seventh


1 Answers

Ok so I've found the answer to my question.

The following function in my AppController class is the culrprit:

public function beforeRender() {
    $user_id = $this->Auth->user('id');
    $user = $this->User->read(null, $user_id);
    $this->set('user', $user);
}

For some reason, calling the $this->Model->read() function prevents validation errors from being displayed, and this function was being calling this at the end of every action. Moving it to the beforeFilter() function fixes the problem.

like image 50
james the seventh Avatar answered Sep 20 '22 11:09

james the seventh