четверг, 9 декабря 2010 г.

Смена email пользователем

Часто в целях безопасности при регистрации пользователей их просят подтвердить свой email. Средства для генерации письма с подтверждением и экшены проверки кода подтверждения предоставляет, например, плагин sfApply. Однако, тот же плагин довольно топорно решает проблему смены email пользователем:
unset($this['email'])

Иначе говоря, все, кто хочет изменить email, идут лесом: это не разрешается. Как быть тем, кто хочет сделать более дружелюбный интерфейс?

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

Итак, чтобы разрешить пользователю изменять свой email, нужно:
1. Добавить поле для смены email в форму редактирования своего профиля
2. Добавить в схему данных новое поле new_email
3. В форме редактирования профиля добавляем обработчик данных: если email изменился, то отправляем письмо со сгенерированной ссылкой на подтверждение email

function updateObject($values=null)
  {
    $old_email=$this->getObject()->email;
    $new_email=$this->getValue('email');
    
    parent::updateObject($alues);
    
    if ($old_email != $new_email)
    {
      $this->getObject()->email=$old_email;
      $this->getObject()->new_email=$new_email;
      $this->getObject()->validate=self::createGuid();
      
      $this->getOption('action')->mail(array(
        'subject' => 'Смена email на сайте XXX.XX',
        'name' => $this->getObject()->name,
        'email' => $this->getObject()->new_email,
        'parameters' => array('name' => $this->getObject()->name, 'validate' => $this->getObject()->validate),
        'text' => 'profile/sendValidateEmailText',
        'html' => 'profile/sendValidateEmail'
        ));
      
    }
    
    return $this->getObject();
  }

4. Составляем письмо со ссылкой:

Здравствуйте, 


Вы запросили изменение регистрационного email на сайте XXX.XX. Подтвердите изменение переходом по ссылке:

[php echo url_for('@confirm_new_email?validate='.$validate, true) ]

Если вы не понимаете о чем речь, просто проигнорируйте это письмо.

------
Почтовый робот

5. Добавляем роут для подтверждения смены email

confirm_new_email:
  url:  /profile/confirm_new_email/:validate
  param: { module: profile, action: confirmNewEmail }

6. Экшен обработки подтверждения:

public function executeConfirmNewEmail(sfRequest $request)
  {
    $validate = $this->request->getParameter('validate');

    if (!strlen($validate))
      return 'Invalid';
      
    $user=Doctrine::getTable('sfGuardUser')->findOneByValidate($validate);
    
    if (!$user)
      return 'Invalid';
    
    if (!$user->new_email)
      return 'Invalid';
      
    $user->email=$user->new_email;
    $user->validate=null;
    $user->save();
      
    $this->user = $user;
  }

Комментариев нет:

Отправить комментарий