Symfony 1.4 условная проверка - PullRequest
3 голосов
/ 18 марта 2012

У меня есть форма Profile, которая наследуется от sfGuardRegisterForm

У меня есть эти поля:

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

Обязательные поля:

email_address, country и language

И условия:

  1. Если email_address не равно текущему email_address затем проверьте, является ли он уникальным , затем сохраните его
  2. Если current_password является действительным паролем пользователя, убедитесь, что new_password и password_again равны, и убедитесь, что new_password не равно действительному паролю пользователя

Я просто не могу понять, как реализовать это

EDIT

Спасибо 1ed ваш пример работает, но проблема в том, что я загружаю профиль пользователя и заполняю поля: 'first_name', 'last_name', 'email_address', 'country', 'language' фактическим зарегистрированным пользователем, поэтому в поле email_address будет показан адрес электронной почты:

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

Если пользователь не меняет адрес электронной почты, он всегда будет показывать это сообщение:

Объект с таким же "email_адресом" уже существует.

Я просто хочу пропустить это

Также это $this->getObject()->checkPassword() не работает, всегда показывать это сообщение:

Неверный текущий пароль.

Я использую:

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

Чтобы получить актуальный профиль пользователя

EDIT2

Еще раз спасибо 1ed

Это очень странно, и я становлюсь раздраженным, это ситуация

  1. У меня есть «обходной путь» для этого, но он не соответствует стандарту, я могу заставить его работать, но используя sfContext::getInstance()->getUser()->getGuardUser();, и это будет более ненужный код
  2. Если я использую new ProfileForm($user), автоматически заполняет все поля, это очень хорошо , но Я не могу setDefault() Я не могу установить null или empty любое поле, чтобы я мог ' t использовать doUpdateObject(), поскольку эта функция работает только при обновлении текущих данных, также я протестировал переопределение bind(), save() и т. д. без результатов

Ответы [ 2 ]

5 голосов
/ 18 марта 2012

email_address уникальность: вы должны установить unique: true в схеме, в sfDoctrineGuardPlugin это так по умолчанию, поэтому в BasesfGuardUserForm вы уже должны увидеть уникальный валидатор: sfValidatorDoctrineUnique(array('model' => 'sfGuardUser', 'column' => array('email_address'))

current_password: выследует создать валидатор постов типа обратного вызова для этого

// 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);
}
0 голосов
/ 18 марта 2012

Я попытаюсь объяснить это в методических терминах вместо того, чтобы дать вам большой блок кода .... Итак, во-первых, вы хотите , если (email_addr! = Current_email) , и если это правда, продолжайте делать if (new_pass! = Current_pass) , затем убедитесь, что if (new_pass == new_pass_again) Внутри всех этих IF, вы можете вернуть true / false или какой-то другой флаг, или просто // сделать код внутри скобок: p

РЕДАКТИРОВАТЬ: заключать эти IF в: if (страна! = NULL && язык! = NULL && email_addr! = NULL)

...