Symfony 1.4条件验证

时间:2012-03-17 23:46:51

标签: php symfony1 symfony-1.4

我有一个继承自Profile

sfGuardRegisterForm表单

我有这些字段:

$this->useFields(
    array('first_name', 
          'last_name',
          'email_address',
          'country',
          'language',
          'current_password',
          'new_password',
          'password_again',
    )
);

必填字段为:

email_addresscountrylanguage

条件是:

  1. 如果email_address与当前email_address不相等 然后检查它是否唯一然后保存
  2. 如果current_password是用户的实际密码,请验证new_passwordpassword_again是否相等,并验证new_password是否不等于实际密码用户
  3. 我无法弄清楚如何实现这个

    修改

    感谢 1ed 您的示例有效,但问题是我加载了用户个人资料,并填写了字段'first_name', 'last_name', 'email_address', 'country', 'language'和实际登录用户,因此email_address字段将显示电子邮件地址:

    //...
    $this->widgetSchema['email_address']->setDefault($this->_user->getEmailAddress());
    //...
    

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

      

    已存在具有相同“email_address”的对象。

    我只是想跳过那个

    $this->getObject()->checkPassword()无效,请始终显示以下消息:

      

    当前密码不正确。

    我用:

      

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

    获取实际的用户个人资料

    EDIT2

    再次感谢 1ed

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

    1. 我有一个“解决方法”,但它没有遵循标准,我可以使它工作,但使用sfContext::getInstance()->getUser()->getGuardUser();,这将是更多的不必要的代码
    2. 如果我使用new ProfileForm($user)自动填充所有字段,那就非常好我不能setDefault()我无法设置null或{{ 1}}任何字段,因此我无法使用empty,因为此功能仅在更新当前数据时有效,我还测试了覆盖doUpdateObject()bind()等没有结果

2 个答案:

答案 0 :(得分:5)

email_address唯一性:您应该在架构中设置unique: true,默认情况下设置为sfDoctrineGuardPlugin,因此在BasesfGuardUserForm中您应该会看到唯一的验证器:sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address')) < / p>

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;
}

或者你可以创建一个自定义的帖子验证器,但我认为没有必要。

修改

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

// 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);
}

答案 1 :(得分:0)

我会尝试用有条不紊的方式解释这一点,而不是给你一大堆代码.... 首先,你要 if(email_addr!= current_email),如果这是真的,继续做 if(new_pass!= current_pass)然后继续确保 if(new_pass == new_pass_again) 在所有这些IF中,你可以返回一个真/假或某种标志,或只是在括号内 // do code :p

编辑:将这些IF包含在: if(country!= NULL&amp;&amp; language!= NULL&amp;&amp; email_addr!= NULL)