php - Triggering model validation with CakePHP -
i'm creating form users can change passwords. form in settings controller, i'm saving data users table.
i have following form
settings/index.ctp echo $this->form->create('settings'); echo $this->form->input('current_password'); echo $this->form->input('password'); echo $this->form->input('repass', array('type'=>'password', 'label'=>'re-enter password')); echo $this->form->end(__('submit')); here's setting model
function equaltofield($array, $field) { print_r($array); //check see if being triggered...it's not! return strcmp($this->data[$this->alias][key($array)], $this->data[$this->alias][$field]) == 0; } public function beforesave() { if (isset($this->data[$this->alias]['password'])) { $this->data[$this->alias]['password'] = authcomponent::password($this->data[$this->alias]['password']); } return true; } public $validate = array( 'password' => array( 'required' => array( 'rule' => array('minlength', '8'), 'message' => 'a password minimum length of 8 characters required' ) ), 'repass' => array( 'required' => array( 'rule' => array('equaltofield', 'password'), 'message' => 'passwords not match' ) ) ); and code in settingscontroller save it
$password = security::hash($this->request->data['settings']['current_password'], null, true); $this->loadmodel('user'); $options = array('conditions' => array('user.' . $this->user->primarykey => authcomponent::user('id'))); $user = $this->user->find('first', $options); if($user['user']['password'] == $password){ //current password match $this->user->id = authcomponent::user('id'); $this->user->savefield('password',security::hash($this->request->data['settings']['password'], null, true)); } else{ $this->session->setflash('current password incorrect'); } what doing incorrectly validation isn't triggering? i'd prefer keep in settingscontroller if possible. also, before mentions plan on making current password match 1 of validation criteria...just working.
update - decided digging around
in /lib/model/model.php went validator function , printed validator object, here's found
([validate] => array ( [password] => array ( [required] => array ( [rule] => array ( [0] => minlength [1] => 8 ) [message] => password minimum length of 8 characters required ) ) [repass] => array ( [required] => array ( [rule] => array ( [0] => equaltofield [1] => password ) [message] => passwords not match ) ) ) [usetable] => settings [id] => [data] => array ( [setting] => array ( [settings] => array ( [current_password] => current_pass [password] => testpass1 [repass] => testpass2 ) ) ) i'm not sure if that's want, it's using settings table , i'm saving users table. changed value users (by manually setting value in function), didn't change anything.
when use following suggested, pulls validation usermodel not settings
$this->user->set($this->request->data); if($this->user->validates() == true){
ok, let's start fresh, new answer. there various problems here.
1. mixing models
you defining validation rules , stuff on setting model, in code snippet using user model saving data, if @ all, apply validation rules defined on user model. while it's possible use different model validation saving, wouldn't recommend that, instead use user model these jobs.
that means, put validation rules , methods in user model (that linked users table).
2. lowercase/plural notation model names
you using lowercase/plural notation model names, should singular starting capital letter:
$this->form->create('setting'); $this->request->data['setting'] please note demonstration purposes, mentioned above should use user model, ie:
$this->form->create('user'); $this->request->data['user'] 3. validation applied explicitly passed data only
model::savefield() validates data explicitly passed it, ie validate password field, , couldn't access other fields validation methods since data not set on model.
so instead you'll either have use model::save() list of allowed fields supplied (you utilize model::set()):
$this->user->id = authcomponent::user('id'); $this->user->save($this->request->data, true, array('password', 'repass')); or trigger validation manually:
$this->user->id = authcomponent::user('id'); $this->user->set($this->request->data); if($this->user->validates() === true) { $this->user->savefield('password', security::hash($this->request->data['user']['password'], null, true)); } note in scenario use different model validation, ie:
$this->setting->set($this->request->data); if($this->setting->validates() === true) { $this->user->savefield('password', security::hash($this->request->data['user']['password'], null, true)); } however, think it's better use user model, if necessary change validation rules dynamically fit needs. example removing rules:
$this->user->validator()->remove('field_x') ->remove('field_y') ->remove('field_z'); or overriding validation rules:
$this->user->validate = array ( ... ); however, both best done within model.
4. triggering validation model::savefield()
last not least, model::savefield() method has 3 parameters, third 1 either boolean value (defaults false), defining whether or not use validation, or array takes options validate, callbacks , countercache.
so have set true third parameter in order validation being triggered model::savefield() @ all:
$this->user->savefield('password', security::hash($this->request->data['user']['password'], null, true), true); ps. aware hashing twice? first directly when passing data model::savefield(), , second time in model::beforesave().
Comments
Post a Comment