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