Symfony 1.4条件验证

ttt*_*ony 3 php symfony1 symfony-1.4

我有一个Profile继承自的表格sfGuardRegisterForm

我有这些领域:

$this->useFields(
    array('first_name', 
          'last_name',
          'email_address',
          'country',
          'language',
          'current_password',
          'new_password',
          'password_again',
    )
);
Run Code Online (Sandbox Code Playgroud)

必填字段是:

email_address,countrylanguage

条件是:

  1. 如果它email_address与电流不相等,email_address 则检查它是否唯一然后保存
  2. 如果current_password是用户的实际密码,然后验证,如果new_passwordpassword_again是平等的,并确认new_password不等于用户的实际密码

我只是无法弄清楚如何实现这一点

编辑

谢谢1ed您的示例有效,但问题是我加载用户配置文件并填写字段:'first_name', 'last_name', 'email_address', 'country', 'language'使用实际登录的用户,因此该email_address字段将显示电子邮件地址:

//...
$this->widgetSchema['email_address']->setDefault($this->_user->getEmailAddress());
//...
Run Code Online (Sandbox Code Playgroud)

如果用户不更改电子邮件,它将始终显示此消息:

已存在具有相同"email_address"的对象.

我只想跳过那个

$this->getObject()->checkPassword()也不起作用,总是显示此消息:

当前密码不正确.

我用:

$ this - > _ user = sfContext :: getInstance() - > getUser() - > getGuardUser();

获取实际的用户个人资料

EDIT2

再次感谢1ed

这非常奇怪,我感到沮丧,这就是情况

  1. 我有一个"解决方法",但它不符合标准,我可以使它工作但使用sfContext::getInstance()->getUser()->getGuardUser();它将是更多的不必要的代码
  2. 如果我使用new ProfileForm($user)自动填充的所有字段,这是非常好的,但我不能setDefault(),我不能设置nullempty任何领域,所以我不能使用doUpdateObject(),因为此功能只适用在当前数据更新,还我已经测试压倒一切bind(),save()等没有结果

1ed*_*1ed 5

email_address uniqueness:你应该unique: true在架构中设置,sfDoctrineGuardPlugin默认是这种情况,所以BasesfGuardUserForm你应该看到一个唯一的验证器:sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))

current_password:你应该为此创建一个回调类型的post验证器

// in sfGuardRegisterForm::configure()

// these fields can be blank
$this->getValidator('current_password')->setOption('required', false);
$this->getValidator('new_password')->setOption('required', false);
$this->getValidator('password_again')->setOption('required', false);

// check the current password (this validator is not `required` by default)
$this->mergePostValidator(new sfValidatorCallback(array(
  'callback' => array($this, 'checkPassword'),
), array(
  'invalid' => 'Incorrect current password.'
)));

// add this method to the same form class
public function checkPassword(sfValidatorBase $validator, array $values, array $arguments)
{
  // if a new password is given check whether the old one is correct or not and rise an error if not correct
  if(0 != strlen($values['new_password']) && !$this->getObject()->checkPassword($values['current_password']))
  {
    throw new sfValidatorErrorSchema($validator, array(
      'current_password' => new sfValidatorError($validator, 'invalid')
    ));
  }

  return $values;
}
Run Code Online (Sandbox Code Playgroud)

或者,您可以创建自定义帖子验证器,但我认为没有必要.

编辑:

如果您希望显示空的电子邮件地址,就像密码字段一样,将这些添加到您的表单类:

// at form load remove the default value
protected function updateDefaultsFromObject()
{
  parent::updateDefaultsFromObject();

  if (isset($this['email_address']))
  {
    $this->setDefault('email_address', '');
  }
}

// before save remove empty email address
protected function doUpdateObject($values)
{
  if (isset($values['email_address']) && 0 == strlen($values['email_address']))
  {
    unset($values['email_address']);
  }

  parent::doUpdateObject($values);
}
Run Code Online (Sandbox Code Playgroud)