2012-02-14 41 views
1

我有一個自定義驗證器的表單,他們的工作就像一個魅力,但我添加一個新的驗證程序時遇到了麻煩,其作用與其他人略有不同。Symfony2 - 如何在CallbackValidator中使用實體變量?

基本上我需要檢查表格中的數據與我通常可以從實體中提取的值。

在這種情況下,我需要抓取用戶密碼salt(使用$ user-> getSalt())。問題似乎是CallbackValidator類不能接受任何其他數據,而不是$ form。

我的代碼:

$user = $this->get('security.context')->getToken()->getUser(); 

    $form = $this->createFormBuilder($user) 
      ->add('password', 'password') 
      ->add('newPassword', 'password', array('label' => 'New Password', 'property_path' => false)) 
      ->add('confirmPassword', 'password', array('label' => 'Confirm Password', 'property_path' => false)) 
      ->addValidator(new CallbackValidator(function($form) 
      { 
       $encoder = new MessageDigestPasswordEncoder('sha1', false, 1); 
       $password = $encoder->encodePassword($form['password']->getData(), $user->getSalt()); 

       if($password != $user->getPassword()) { 
        $form['password']->addError(new FormError('Incorrect password')); 
       } 
       if($form['confirmPassword']->getData() != $form['newPassword']->getData()) { 
        $form['confirmPassword']->addError(new FormError('Passwords must match.')); 
       } 
       if($form['newPassword']->getData() == '') { 
        $form['newPassword']->addError(new FormError('Password cannot be blank.')); 
       } 
      })) 
      ->getForm(); 

現在,這是錯誤我得到:

Fatal error: Call to a member function getSalt() on a non-object in /Sites/src/UserBundle/Controller/DashboardController.php on line 57 

線57的存在:

$password = $encoder->encodePassword($form['password']->getData(), $user->getSalt()); 

我曾嘗試過各種東西,試圖通鹽到CallbackValidator,到目前爲止唯一的方法是將它作爲hiddne字段添加到表單中,但這是不可接受的,因爲它是一個安全風險,我也需要添加散列密碼作爲隱藏字段,以匹配輸入。

必須有一個更簡單的方法來做到這一點?

回答

6

您的$ user變量來自$this->get('security.context')->getToken()->getUser();未在匿名函數的範圍內定義。

與從父範圍(自動關閉)繼承的JavaScript等語言相反,您需要明確地要求php執行此操作。 的use關鍵字是爲在製作:http://php.net/manual/en/functions.anonymous.php

$user = new User; 
function($form) use($user) { 

}; 

這裏是一個更好的解釋:) Javascript closures vs PHP closures, what's the difference?

因此,所有你應該做的是修改代碼那樣:

$user = $this->get('security.context')->getToken()->getUser(); 

$form = $this->createFormBuilder($user) 
     ->add('password', 'password') 
     ->add('newPassword', 'password', array('label' => 'New Password', 'property_path' => false)) 
     ->add('confirmPassword', 'password', array('label' => 'Confirm Password', 'property_path' => false)) 
     ->addValidator(new CallbackValidator(function($form) use($user) 
     { 
      $encoder = new MessageDigestPasswordEncoder('sha1', false, 1); 
      $password = $encoder->encodePassword($form['password']->getData(), $user->getSalt()); 

      if($password != $user->getPassword()) { 
       $form['password']->addError(new FormError('Incorrect password')); 
      } 
      if($form['confirmPassword']->getData() != $form['newPassword']->getData()) { 
       $form['confirmPassword']->addError(new FormError('Passwords must match.')); 
      } 
      if($form['newPassword']->getData() == '') { 
       $form['newPassword']->addError(new FormError('Password cannot be blank.')); 
      } 
     })) 
     ->getForm(); 
+0

超級,這似乎有助於...!我現在遇到了驗證器本身的問題。看來$ user-> getPassword()是取得未加密的密碼(不知道怎麼樣,我把它設置爲sha1),所以我試圖比較$ form ['password'] - > getData()到用戶密碼,但不我輸入了什麼,它驗證了它,啊! – 2012-02-14 16:19:14

+0

Form綁定將在'$ user-> password'中寫入'password'字段值。因此,'$ user-> getPassword()'和$ form ['password'] - > getdata()'完全一樣。您應該刪除' - > add('password','password')'行,以便表單不會更新$ user->密碼值。 – Florian 2012-02-14 16:39:20

+0

哈哈,我真的只是想出來並修復它!剛回來給你打個招呼:D – 2012-02-14 16:41:59

相關問題