2016-05-04 12 views
0

FOSUserBundleでは、ChangePasswordController - > changePasswordActionをオーバーライドして、古いパスワードを保存できるようにしました。Symfony2 FOSUserBundleでは、フォームにカスタムエラーメッセージを投げる方法を教えてください。

私はすべて機能していますが、ユーザーが古いアーカイブされたパスワードを使用して更新しようとすると、カスタムエラーメッセージをフォームに送信する方法がわかりません。ここで

は私の変更は古いパスワードでユーザーの種類は、(「いいえ」)死んだら現時点では、すべての内部 if ($form->isValid()) { ... }

public function changePasswordAction(Request $request) 
{ 
    $user = $this->getUser(); 
    if (!is_object($user) || !$user instanceof UserInterface) { 
     throw new AccessDeniedException('This user does not have access to this section.'); 
    } 

    /** @var $dispatcher \Symfony\Component\EventDispatcher\EventDispatcherInterface */ 
    $dispatcher = $this->get('event_dispatcher'); 

    $event = new GetResponseUserEvent($user, $request); 
    $dispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_INITIALIZE, $event); 

    if (null !== $event->getResponse()) { 
     return $event->getResponse(); 
    } 

    /** @var $formFactory \FOS\UserBundle\Form\Factory\FactoryInterface */ 
    $formFactory = $this->get('fos_user.change_password.form.factory'); 

    $form = $formFactory->createForm(); 
    $form->setData($user); 

    $form->handleRequest($request); 

    if ($form->isValid()) { 
     /** @var $userManager \FOS\UserBundle\Model\UserManagerInterface */ 
     $userManager = $this->get('fos_user.user_manager'); 

     if (0 !== strlen($password = $form->getData()->getPlainPassword())) { 
      $newPassword = $userManager->getEncodedPassword($user, $password); 

      // get the number of Archived Passwords to be saved 
      $numArchives = 0; 
      $company = $user->getCompany(); 
      if (!empty($company)) { 
       $passwordAllowedSaves = $company->getPasswordAllowedSaves(); 
       if (!empty($passwordAllowedSaves)) { 
        $numArchives = $passwordAllowedSaves; 
       } 
      } 

      // check archived passwords 
      if ($numArchives > 0) { 
       $oldestArchive = null; 
       $passwordAlreadyArchived = false; 

       $archives = $user->getArchives(); 
       foreach ($archives as $archive) { 
        // track the oldest archive 
        if (empty($oldestArchive)) { 
         $oldestArchive = $archive; 
        } else { 
         if ($oldestArchive->getCreated() < $archive->getCreated()) { 
          $oldestArchive = $archive; 
         } 
        } 

        // check the newPassword is not archived 
        if ($newPassword == $archive->getPassword()) { 
         $passwordAlreadyArchived = true; 
        } 
       } 

       // if this is an archived password it can't be saved 
       if ($passwordAlreadyArchived) { 
        die('nope'); 
        //$event = new FormEvent($form, $request); 
        //$dispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_SUCCESS, $event); 
       } else { 
        // save password in a new Archive 
        $entityManager = $this->getDoctrine()->getManager(); 
        $archive = new Archive(); 
        $archive->setPerson($user) 
         ->setPassword($newPassword) 
         ->setCreated(new \DateTime()); 

        $entityManager->persist($archive); 
        $entityManager->flush(); 

        // Make sure that there are not too many saved 
        if (count($archives) + 1 > $numArchives) { 
         $user->removeArchive($oldestArchive); 
        } 
       } 
      } 
     } 

     $event = new FormEvent($form, $request); 
     $dispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_SUCCESS, $event); 

     $userManager->updateUser($user); 

     if (null === $response = $event->getResponse()) { 
      $url = $this->generateUrl('person_show', array('id' => $user->getId())); 
      $response = new RedirectResponse($url); 
     } 

     $dispatcher->dispatch(FOSUserEvents::CHANGE_PASSWORD_COMPLETED, new FilterUserResponseEvent($user, $request, $response)); 

     return $response; 
    } 

    return $this->render('FOSUserBundle:ChangePassword:changePassword.html.twig', array(
     'form' => $form->createView(), 
    )); 
} 

あり、私のchangePasswordActionです。実行されます。私はそれを何に置き換えるべきかわからないので、私はフォームで素晴らしいメッセージを得ることができます。

答えて

0

フォームにカスタム制約を追加することをお勧めします。フォームのオーバーライドに関する詳細はhereをご覧ください。

そして、あなたはこのコントローラをすべてオーバーライドする必要はありませんでした。あなたは他のいくつかの方法でそれを行うことができます。

  1. FOSUserEvents::CHANGE_PASSWORD_SUCCESSイベントのリスナーを作成し、古いパスワードを処理中にアーカイブします。
  2. DoctirneのpostUpdateエンティティイベントのリスナーを作成します。 (詳細情報here
関連する問題