symfony2 passing multiple services

symfony2のサービスコンテナ(Service Container)を使って複数のサービスを受け渡す方法

例えば、ログインしていないユーザにID、パスワード、新しいパスワードを入力してもらって、パスワード更新をする処理の場合。Validatorの中では、

1.現状のユーザ情報を取得するためにdoctrine.orm.entity_managerが必要
2.パスワードを暗号化して比較するのにsecurity.encoder_factoryが必要

従って、services.xmlには以下のように記載する

<services>
  <service id="hc100_validator.constraint.validpassword" class="Hc100\DemoBundle\Validator\Constraints\ValidPasswordValidator">
    <argument type="service" id="doctrine.orm.entity_manager"/>
    <argument type="service" id="security.encoder_factory"/>
    <tag name="validator.constraint_validator" alias="validpassword" />
  </service>
</services>

後はカスタムバリデーターの中で以下のようにして受け取れる

  private $entityManager;
  private $encoderFactory;

  public function __construct(EntityManager $entityManager, EncoderFactory $encoderFactory)
  {
    $this->entityManager = $entityManager;
    $this->encoderFactory = $encoderFactory;
  }

ちなみに、フォーム内の複数の要素をバリデーションに使う場合はConstraintに以下を定義

  public function getTargets()
  {
    return Constraint::CLASS_CONSTRAINT;
  }

そうすれば、バリデーターでは$valueではなく、Entityとしてうけとれる

  public function validate($user, Constraint $constraint)
  {
    $database_user = $this->entityManager->getRepository('Hc100DemoBundle:User')
      ->findOneBy(array('userId' => $user->getUserId()));
    if (!$database_user) {
      $this->context->addViolation($constraint->message);
    }

    $encoder = $this->encoderFactory->getEncoder($database_user);
    if ($database_user->getPassword() != $encoder->encodePassword($user->getPassword(), $database_user->getSalt())) {
      $this->context->addViolation($constraint->message);
    }
  }

この場合はAssertはメソッドにではなくて、クラスに指定する必要があるのでよろしく!

Share on Google+Tweet about this on TwitterShare on TumblrShare on Facebook

コメントを残す

メールアドレスが公開されることはありません。 * が付いている欄は必須項目です