3 Stimmen

Symfony 1.4 bedingte Validierung

Ich habe eine Profile Formular, das erbt von sfGuardRegisterForm

Ich habe diese Felder:

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

Erforderliche Felder sind:

email_address , country y language

Und die Bedingungen sind:

  1. Wenn die email_address ist nicht gleich dem aktuellen email_address dann prüfen, ob es sich um einzigartig dann speichern Sie es
  2. Wenn die current_password das tatsächliche Passwort des Benutzers ist, dann prüfen Sie, ob new_password y password_again gleich sind, und überprüfen Sie, ob die new_password nicht mit dem tatsächlichen Passwort des Benutzers übereinstimmt

Ich kann nur nicht herausfinden, wie ich das umsetzen soll.

EDIT

Danke 1ed Ihr Beispiel funktioniert, aber das Problem ist, dass ich das Benutzerprofil lade und die Felder ausfülle: 'first_name', 'last_name', 'email_address', 'country', 'language' mit dem aktuell angemeldeten Benutzer, so dass die email_address Feld wird die E-Mail-Adresse angezeigt:

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

Wenn der Benutzer die E-Mail nicht ändert, wird diese Meldung immer angezeigt:

Ein Objekt mit der gleichen "email_address" existiert bereits.

Ich möchte das einfach überspringen

Auch diese $this->getObject()->checkPassword() nicht funktioniert, wird immer diese Meldung angezeigt:

Falsches aktuelles Passwort.

Ich benutze:

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

So erhalten Sie das aktuelle Benutzerprofil

EDIT2

Nochmals vielen Dank 1ed

Das ist sehr seltsam und ich bin frustriert, das ist die Situation

  1. Ich habe einen "Workaround" für dieses Problem, aber er entspricht nicht dem Standard. Ich kann das Problem lösen, indem ich sfContext::getInstance()->getUser()->getGuardUser(); und es wird mehr unnötiger Code sein
  2. Wenn ich die new ProfileForm($user) füllt automatisch alle Felder aus, das ist sehr gut sondern Ich kann nicht setDefault() Ich kann nicht einstellen null o empty irgendein Feld, so dass ich nicht verwenden kann doUpdateObject() weil diese Funktion nur funktioniert, wenn die aktuellen Daten aktualisiert werden, außerdem habe ich getestet, dass die Funktion bind() , save() usw. ohne Ergebnis

5voto

1ed Punkte 3638

Einzigartigkeit der email_Adresse: Sie sollten die unique: true im Schema, in sfDoctrineGuardPlugin das ist standardmäßig der Fall, also in BasesfGuardUserForm sollten Sie bereits einen eindeutigen Validator sehen: sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))

current_password: Sie sollten einen Callback-Typ Post-Validator für diese Funktion erstellen.

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

Alternativ können Sie auch einen benutzerdefinierten Post-Validator erstellen, aber ich denke, das ist nicht notwendig.

EDITAR:

Wenn Sie leere E-Mail-Adressen anzeigen möchten, fügen Sie diese ebenso wie die Passwortfelder zu Ihrer Formularklasse hinzu:

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

0voto

Kinz Punkte 300

Ich werde versuchen, dies methodisch zu erklären, anstatt Ihnen einen großen Block von Code zu geben.... Zuerst müssen Sie also if (email_addr != current_email) und wenn das stimmt, machen Sie weiter mit if (neuer_pass != aktueller_pass) dann weitergehen, um sicherzustellen, dass if (new_pass == new_pass_again) Innerhalb all dieser IFs können Sie ein true/false oder eine Art Flag zurückgeben, oder einfach //Code ausführen innerhalb der Klammern :p

EDITAR: diese IFs einschließen: if (country != NULL && language != NULL && email_addr != NULL)

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X