Symfony2 – Как использовать переменные Entity в CallbackValidator?

У меня есть форма, построенная с помощью некоторых настраиваемых валидаторов, и они работают как шарм, но мне сложно добавить новый валидатор, который работает несколько иначе, чем другие.

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

В этом случае мне нужно захватить соль паролей пользователей (используя $ 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, но это неприемлемо, так как это угроза безопасности, и мне также нужно будет добавить хешировать пароль как скрытое поле, чтобы соответствовать входному сигналу.

Должен быть более простой способ сделать это?

Ваша переменная $ 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 против закрытия PHP, в чем разница?

Итак, все, что вам нужно сделать, это изменить свой код следующим образом:

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