我正在创建一个表单,以便用户可以更改密码。此表单在我的设置控制器中,但我正在将数据保存到用户表中。
我有以下表格
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'));
这是我的设定型号
function equalToField($array, $field) {
print_r($array); //check to see if it was even 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 with a minimum length of 8 characters is required'
)
),
'repass' => array(
'required' => array(
'rule' => array('equalToField', 'password'),
'message' => 'Passwords do not match'
)
)
);
在我的设置控制器中保存的代码
$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 is incorrect');
}
我做错了什么,验证没有触发?如果可能的话,我更愿意把它保存在我的SettingsController中。此外,在任何人提到它之前,我计划将当前密码匹配作为验证标准之一。。。只要我让它工作。
更新-我决定在周围做一些挖掘
在/lib/Model/Model.php中,我转到验证器函数并打印验证器对象,以下是我发现的
([validate] => Array (
[password] => Array (
[required] => Array (
[rule] => Array (
[0] => minLength
[1] => 8 )
[message] => A password with a minimum length of 8 characters is required ) )
[repass] => Array (
[required] => Array (
[rule] => Array (
[0] => equalToField
[1] => password )
[message] => Passwords do not match
) ) )
[useTable] => settings
[id] =>
[data] => Array (
[Setting] => Array (
[settings] => Array (
[current_password] => current_pass
[password] => testpass1
[repass] => testpass2
) ) )
我不确定这是否是我想要的,但它使用了设置表,我正在保存到用户表中。我将该值更改为用户(通过手动设置该函数中的值),但没有更改任何内容。
当我按照建议使用以下内容时,它从UserModel而不是Settings 中提取验证
$this->User->set($this->request->data);
if($this->User->Validates() == true){
好的,让我们从一个全新的答案开始。这里有各种各样的问题。
1.混淆模型
您在Setting
模型上定义验证规则和内容,但在代码片段中,您使用User
模型来保存数据,因此,如果有,它将应用在User
模型上定义的验证规则。因此,虽然可以使用不同于保存的模型进行验证,但我不建议这样做,而是对所有这些作业使用User
模型。
这意味着,将验证规则和方法放在User
模型中(希望它能链接到users
表)。
2.型号名称的小写/复数表示法
型号名称使用小写/复数表示法,其中应以大写字母开头的单数形式:
$this->Form->create('Setting');
$this->request->data['Setting']
请注意,这只是为了演示,如上所述,您应该使用User
模型,即:
$this->Form->create('User');
$this->request->data['User']
3.验证仅应用于显式传递的数据
Model::saveField()
只验证显式传递给它的数据,即它只验证password
字段,并且您不能从验证方法访问任何其他字段,因为数据没有在模型上设置。
因此,您必须使用Model::save()
并提供允许的字段列表(您也可以使用Model::set()
):
$this->User->id = AuthComponent::user('id');
$this->User->save($this->request->data, true, array('password', 'repass'));
或者手动触发验证:
$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));
}
请注意,在这种情况下,您也可以使用不同的模型进行验证,即:
$this->Setting->set($this->request->data);
if($this->Setting->validates() === true)
{
$this->User->saveField('password', Security::hash($this->request->data['User']['password'], NULL, true));
}
但是,我认为最好使用用户模型,如果有必要,可以动态更改验证规则,使其符合您的需求。例如,通过删除规则:
$this->User->validator()->remove('field_x')
->remove('field_y')
->remove('field_z');
或者通过覆盖验证规则:
$this->User->validate = array
(
...
);
然而,两者都最好在模型内完成。
4.使用Model::saveField()
触发验证
最后但并非最不重要的是,Model::saveField()
方法有3个参数,其中第三个参数是定义是否使用验证的boolean
值(默认为false
),或者是采用选项validate
、callbacks
和counterCache
的array
。
因此,您必须将true
设置为第三个参数,以便由Model::saveField()
触发验证:
$this->User->saveField('password', Security::hash($this->request->data['User']['password'], NULL, true), true);
ps。你知道你目前正在进行两次散列运算吗?第一次是在将数据传递给Model::saveField()
时,第二次是在Model::beforeSave()
中。