CakePHP: редактировать пользователей без изменения пароля

Как сохранить пользователей в моем приложении CakePHP, не требуя, чтобы они каждый раз меняли свой пароль?

У меня есть код для проверки двух полей пароля и применения некоторых правил проверки, которые отлично подходят для регистрации и изменения паролей в представлении "редактировать". Однако, как мне пропустить правила проверки и сохранить пароль, если поля пароля остались пустыми в представлении "Изменить"? Очевидно, я не хочу пропустить это требование при регистрации.

register.ctp и edit.ctp:

echo $form->create('User');
echo $form->input('username');
echo $form->input('pwd');
echo $form->input('pwd_repeat');
echo $form->end('Submit');

Правила проверки User.ctp:

'pwd' => array(
        'length' => array(
            'rule'      => array('between', 8, 40),
            'message'   => 'Your password must be between 8 and 40 characters.',
        ),
    ),
    'pwd_repeat' => array(
        'length' => array(
            'rule'      => array('between', 8, 40),
            'message'   => 'Your password must be between 8 and 40 characters.',
        ),
        'compare'    => array(
            'rule'      => array('validate_passwords'),
            'message' => 'The passwords you entered do not match.',
        ),
    ),

и логика User.ctp перед сохранением:

public function validate_passwords() { //password match check
return $this->data[$this->alias]['pwd'] === $this->data[$this->alias]['pwd_repeat'];
}

public function beforeSave($options = array()) { //set alias to real thing and hash password

    $this->data['User']['password'] = $this->data[$this->alias]['pwd'];
    $this->data['User']['password'] = AuthComponent::password($this->data['User']['password']);
    return true;
}

4 ответа

Решение
var $validate = array(
    'pwd' => array(
        'length' => array(
            'rule'      => array('between', 8, 40),
            'message'   => 'Your password must be between 8 and 40 characters.',
            'on'        => 'create',  // we only need this validation on create
        ),
    ),

    // if we have a password entered, we need it to match pwd_repeat (both create and update)
    // we no longer need the length validation
    'pwd_repeat' => array(
        'compare' => array(
            'rule'    => array('validate_passwords'),
            'message' => 'Please confirm the password',
        ),
    ),
);


public function validate_passwords() { //password match check
    return $this->data[$this->alias]['pwd'] === $this->data[$this->alias]['pwd_repeat'];
}

public function beforeSave($options = Array()) {
    // if we have a password, we hash it before saving
    if (isset($this->data[$this->alias]['pwd'])) {
        $this->data[$this->alias]['password'] = AuthComponent::password($this->data[$this->alias]['pwd_repeat']);
    }
    return true;
}

Если вы используете CakePHP 2.2:

http://book.cakephp.org/2.0/en/models/data-validation.html

Также в функции beforeSave оберните первые две строки в условные выражения, если оба поля пароля не пусты.

Просто удалите поле из edit.ctp

echo $form->create('User');
echo $form->input('username');
//echo $form->input('pwd');
//echo $form->input('pwd_repeat');
echo $form->end('Submit');

Потому что this->request->data заполняет хешированный пароль в поле пароля. При сохранении пароля пользователя хэшируется снова и становится другим, чем оригинальный

Для тех, кто хочет что-то без изменения модели (и сохранения правила onUpdate при отправке нового пароля): обновление пользователя с паролем или без него - CakePHP

TL; DR:

// add in your view `app/View/Users/edit.ctp`
// a 'fake' field you'll only use on the controller
echo $this->Form->input('new_password');

// add in your controller `app/Model/User.php`
// if we have a new password, create key `password` in data
if(!empty($new_password = $this->request->data['User']['new_password']))
  $this->request->data['User']['password'] = $new_password;
else // else, we remove the rules on password
  $this->User->validator()->remove('password');
Другие вопросы по тегам