2
votes

I'm new to Cake and building an application to learn it. I'm having a few troubles with my user registration system. So far this is my registration code in my Users controller:

public function register() {
    $this->set('title_for_layout', 'Register');
    if ($this->request->is('post')) {
        $this->User->create();
        if ($this->User->save($this->request->data)) {
            $this->Session->setFlash('The user has been saved');
            $this->redirect(array('action' => 'register'));
        } else {
            $this->Session->setFlash('The user could not be saved. Please, try again.');
        }
    }
}

And within my User model I have this method where I hash the passwords:

public function beforeSave() {
    if (isset($this->data[$this->alias]['password'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
    }
    return true;
}

This works, the user is added to my users table in my database with their username, email and hashed password. However, there are no checks done to make sure the username and email are unique.

From my limited understanding, I would need to add some validation rules to my User model to make sure the username and email fields are unique before they're entered into the table? At the moment I just have these validation rules:

public $validate = array(
    'username' => array(
        'required' => array(
            'rule' => array('notEmpty'),
            'message' => 'A username is required'
        )
    ),
    'email' => array(
        'required' => array(
            'rule' => array('notEmpty'),
            'message' => 'An email is required'
        )
    ),
    'password' => array(
        'required' => array(
            'rule' => array('notEmpty'),
            'message' => 'A password is required'
        )
    )
);

Also, my registration form has a Password (confirm) field called passwordConf. I would like to check if the user entered his passwords correctly before they're entered into the users table, but I'm not sure how to do that. I'm guessing that somewhere in my register method I need to check if the two passwords are the same.

Thanks for any help.

2
Why not set up your database such that the Users table requires Username/E-mail to be unique, and doesn't allow you to insert rows that do not adhere to that? Are you using MySQL? - SuperTron
I just added two UNIQUE keys to my users table, one for username and the other for email. However, now Cake just throws out a SQL error rather than a nice error message. I'm sure there's a way to do it in the application, I just don't know how and can't find it in the Cake docs. Either way thanks, those UNIQUE keys should've been added before anyway :) - James Dawson

2 Answers

5
votes

The isUnique rule will work with your username and email fields. Here is a sample of code that shows how to use multiple rules per field:

public $validate = array(
    'username' => array(
        'required' => array(
            'rule' => array('notEmpty'),
            'message' => 'You must enter a username.'
        ),
        'length' => array(
            'rule' => array('between', 3, 15),
            'message' => 'Your username must be between 3 and 15 characters long.'
        ),
        'unique' => array(
            'rule'    => 'isUnique',
            'message' => 'This username has already been taken.'
        )
    ),
    'password' => array(
        'required' => array(
            'rule' => array('notEmpty'),
            'message' => 'You must enter a password.'
        ),
        'length' => array(
            'rule' => array('minLength', '6'),
            'message' => 'Your password must be at least 6 characters long.'
        )
    ),
        'email' => array(
            'email' => array(
            'rule'    => array('email'),
            'message' => 'Please enter a valid email address.'
        )
    )
);

As for comparing the passwords just edit your beforeSave callback and check the passwords against each other, returning true if they match and false if they do not. Something like this:

public function beforeSave() {
    if (isset($this->data[$this->alias]['password'])) {
        if($this->data[$this->alias]['password'] === $this->data[$this->alias]['passwordConf']) {
            $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['password']);
            return true;
        } else {
            return false;
        }
    }
    return true;
}
3
votes

CakePHP actually has a validation rule called isUnique, which you can use to check the username and e-mail. A list of built in rules can be found here. You can use this and the Data Validation Tutorial to check the user name and e-mail. As to checking if the passwords are the same, you MAY be able to use the EqualTo rule shown in the rules list, assuming you can make your validation rules on the fly every request.