2012-03-17 2 views
3

У меня есть Profile форму, которая наследуется от sfGuardRegisterFormSymfony 1,4 условной проверки

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

$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()); 
//... 

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

A n с тем же «email_address» уже существует.

Я просто хочу, чтобы пропустить

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

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

Я использую:

$ это -> _ пользователь = sfContext :: деЫпзЬапсе() -> GetUser() -> getGuardUser();

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

EDIT2

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

Это очень странно, и я получаю frustated, это ситуация

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

ответ

5

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

в качестве альтернативы вы можете создать собственный почтовый валидатор, но я думаю, что это не нужно.

EDIT:

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

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

Спасибо, что у меня есть обновил вопрос – tttony

+1

Я думаю, что валидаторы не работают, потому что вы не устанавливаете базовый пользовательский объект. И этот '$ this -> _ user = sfContext :: getInstance() -> getUser() -> getGuardUser();' не очень хорошая идея, всегда старайтесь избегать использования sfContext, если это возможно. В действии, где вы создаете форму, вы должны получить объект пользователя и передать его в форму, и все значения будут заполнены на основе пользователя. '$ user = $ this-> getUser() -> getGuardUser(); $ this-> form = new ProfileForm ($ user); '. Вызов 'setDefault()' не требуется. – 1ed

+0

Одна вещь mote ... валидатор 'sfValidatorSchemaCompare' не требуется, поскольку он уже находится в' BasesfGuardUserAdminForm', поэтому я удалил это. – 1ed

0

постараюсь объясните это в методических терминах вместо того, чтобы дать вам большой блок кода .... Итак, сначала вы хотите если (EMAIL_ADDR! = CURRENT_EMAIL) и если это правда, идти делать если (new_pass! = Current_pass) затем следуют далее, чтобы убедиться если (new_pass == new_pass_again) внутри все этот МСФ, вы можете вернуть истинное/ложное или какое-то флаг, или просто // сделать код в скобках: р

EDIT: упаковывают этот МСФ в: если (страна ! = NULL & & язык! = NULL &EMAIL_ADDR = NULL)

+0

Спасибо Я сделал это, проблема, что я» m, теперь нужно проверить, является ли ** email_address **! = ** actual_email ** и проверить, не является ли его уникальным в базе данных – tttony

+0

Ну, для этого вам нужно будет получить каждое письмо в БД и поместить их в массив, затем сделайте foreach() и сравните их, а затем верните, если это правда или нет. & для текущей электронной почты просто пройдите через БД и выберите пользователей USERNAME и просмотрите индексы пользователей, получите current_email и сравните их. Логика, подобная этой, может сбивать с толку, и я не работаю с БД много, но если вы ищете в Google что-то вроде _ Как искать все индексы db в php mysql/sqlite_, вы должны придумать somethin ' – Kinz

Смежные вопросы