Symfony 1.4 conditional validation

I have a form Profile

that inherits fromsfGuardRegisterForm

I have the following fields:

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

      

Required fields:

email_address

, country

andlanguage

And conditions:

  • If email_address

    not the same as the current one email_address

    then check if it is unique then save it
  • If current_password

    is the actual user password, then check if new_password

    and are equal password_again

    and make sure it is new_password

    not the same as the actual user password

I just can't figure out how to implement this

EDIT

Thanks 1ed your example works, but the problem is I load the user profile and I fill in the fields: 'first_name', 'last_name', 'email_address', 'country', 'language'

with the actual logged in user, so the field email_address

will show the email

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

      

Unless the user changes their email address, they will always show this message:

An object with the same "email_address" already exists.

I just want to miss that

Also this one $this->getObject()->checkPassword()

doesn't work, always show this message:

Invalid current password.

I use:

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

Get the actual user profile

EDIT2

Thanks again 1ed

This is very strange and I get a swirl, this is the situation

  • I have a "workaround" for this, but it is not in the standard, I can get it to work, but using sfContext::getInstance()->getUser()->getGuardUser();

    and it will be more unnecessary code.
  • If I use new ProfileForm($user)

    auto-fills all fields, that's very good , but I can't setDefault()

    I can't set null

    or empty

    any field that I can't use doUpdateObject()

    , because this function only works when the current data is updated, also I checked the override bind()

    , save()

    etc. etc. no results
+3


source to share


2 answers


uniqueness email_address: you must set unique: true

in the schema, in sfDoctrineGuardPlugin

, which is the default case, so in BasesfGuardUserForm

you should see the unique validator already:sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))

current_password: you must create a callback type message validator for this

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

      

Alternatively you can create a personalized post validator, but I think this is not necessary.



EDIT:

If you want to display a blank email in the same way as password fields, add them to the form class:

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

      

+5


source


I'll try to explain this in methodical terms instead of giving you a big block of code .... So first you want if (email_addr! = Current_email) , and if that's true, keep doing if (new_pass! = Current_pass) , then do to make sure that if (new_pass == new_pass_again) Inside all these IFs you can return true / false or some kind of flag or just // do the code inside the brackets: p



EDIT: wrap these IFs in: if (country! = NULL && language! = NULL & email_addr! = NULL)

0


source







All Articles