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