[英]How to provide SF/Sonata RepeatedType (pw) on User/edit for Admins
我們正在使用 symfony 4.4 並使用奏鳴曲進行實體管理。 我們實現了一個非常輕量級的用戶管理,並且還可以在用戶編輯頁面的第二個選項卡中向用戶添加產品。 所以現在管理員想要將產品分配給用戶,但問題是密碼字段不允許這種行為。 首先密碼字段是必需的,但將其設置為 false 根本沒有幫助,因為該字段只是被提交為空。
所以我嘗試的一個解決方案是在我的管理員 class 中使用 preUpdate function 來防止該錯誤。
public function preUpdate($object)
{
/** @var EntityManagerInterface $em */
$em = $this->getConfigurationPool()->getContainer()->get('Doctrine')->getManager();
/** @var UserRepository $repository */
$repository = $em->getRepository(User::class)->find($object->getId());
$password = $object->getPassword();
if (!empty($password)) {
$salt = md5(time());
$encoderservice = $this->getConfigurationPool()->getContainer()->get('security.encoder_factory');
$encoder = $encoderservice->getEncoder($object);
$encoded_pass = $encoder->encodePassword($object->getPassword(), $salt);
$object->setSalt($salt);
$object->setPassword($encoded_pass);
} else {
$object->setPassword($repository->getPassword());
}
return $object;
}
因此,如果密碼不為空 - 我們采用給定的值並更新密碼。 如果該字段為空,我們使用現有密碼,因此只需添加產品和更新用戶實體就沒有問題。
這很好,但觸發錯誤出現在 preUpdate function 可以提供幫助之前。
所以給定的錯誤是:
Expected argument of type "string", "null" given at property path "password".
沒有 preUpdate 生效。
這里的解決方案是什么?
完整的堆棧跟蹤:
Symfony\Component\PropertyAccess\Exception\InvalidArgumentException:
Expected argument of type "string", "null" given at property path "password".
at vendor/symfony/property-access/PropertyAccessor.php:198
at Symfony\Component\PropertyAccess\PropertyAccessor::throwInvalidArgumentException('string', array(array('file' => '/var/www/vendor/symfony/property-access/PropertyAccessor.php', 'line' => 548, 'function' => 'setPassword', 'class' => 'App\\Entity\\User', 'type' => '->', 'args' => array(null)), array('file' => '/var/www/vendor/symfony/property-access/PropertyAccessor.php', 'line' => 114, 'function' => 'writeProperty', 'class' => 'Symfony\\Component\\PropertyAccess\\PropertyAccessor', 'type' => '->', 'args' => array(array(object(User)), 'password', null)), array('file' => '/var/www/vendor/symfony/form/Extension/Core/DataMapper/PropertyPathMapper.php', 'line' => 86, 'function' => 'setValue', 'class' => 'Symfony\\Component\\PropertyAccess\\PropertyAccessor', 'type' => '->', 'args' => array(object(User), object(PropertyPath), null)), array('file' => '/var/www/vendor/symfony/form/Form.php', 'line' => 632, 'function' => 'mapFormsToData', 'class' => 'Symfony\\Component\\Form\\Extension\\Core\\DataMapper\\PropertyPathMapper', 'type' => '->', 'args' => array(object(RecursiveIteratorIterator), object(User))), array('file' => '/var/www/vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php', 'line' => 109, 'function' => 'submit', 'class' => 'Symfony\\Component\\Form\\Form', 'type' => '->', 'args' => array(array(), true)), array('file' => '/var/www/vendor/symfony/form/Form.php', 'line' => 493, 'function' => 'handleRequest', 'class' => 'Symfony\\Component\\Form\\Extension\\HttpFoundation\\HttpFoundationRequestHandler', 'type' => '->', 'args' => array(object(Form), object(Request))), array('file' => '/var/www/vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php', 'line' => 331, 'function' => 'handleRequest', 'class' => 'Symfony\\Component\\Form\\Form', 'type' => '->', 'args' => array(object(Request))), array('file' => '/var/www/vendor/symfony/http-kernel/HttpKernel.php', 'line' => 158, 'function' => 'editAction', 'class' => 'Sonata\\AdminBundle\\Controller\\CRUDController', 'type' => '->', 'args' => array(null)), array('file' => '/var/www/vendor/symfony/http-kernel/HttpKernel.php', 'line' => 80, 'function' => 'handleRaw', 'class' => 'Symfony\\Component\\HttpKernel\\HttpKernel', 'type' => '->', 'args' => array(object(Request), 1)), array('file' => '/var/www/vendor/symfony/http-kernel/Kernel.php', 'line' => 201, 'function' => 'handle', 'class' => 'Symfony\\Component\\HttpKernel\\HttpKernel', 'type' => '->', 'args' => array(object(Request), 1, true)), array('file' => '/var/www/public/index.php', 'line' => 25, 'function' => 'handle', 'class' => 'Symfony\\Component\\HttpKernel\\Kernel', 'type' => '->', 'args' => array(object(Request)))), 0, 'password')
(vendor/symfony/property-access/PropertyAccessor.php:118)
at Symfony\Component\PropertyAccess\PropertyAccessor->setValue(object(User), object(PropertyPath), null)
(vendor/symfony/form/Extension/Core/DataMapper/PropertyPathMapper.php:86)
at Symfony\Component\Form\Extension\Core\DataMapper\PropertyPathMapper->mapFormsToData(object(RecursiveIteratorIterator), object(User))
(vendor/symfony/form/Form.php:632)
at Symfony\Component\Form\Form->submit(array(), true)
(vendor/symfony/form/Extension/HttpFoundation/HttpFoundationRequestHandler.php:109)
at Symfony\Component\Form\Extension\HttpFoundation\HttpFoundationRequestHandler->handleRequest(object(Form), object(Request))
(vendor/symfony/form/Form.php:493)
at Symfony\Component\Form\Form->handleRequest(object(Request))
(vendor/sonata-project/admin-bundle/src/Controller/CRUDController.php:331)
at Sonata\AdminBundle\Controller\CRUDController->editAction(null)
(vendor/symfony/http-kernel/HttpKernel.php:158)
at Symfony\Component\HttpKernel\HttpKernel->handleRaw(object(Request), 1)
(vendor/symfony/http-kernel/HttpKernel.php:80)
at Symfony\Component\HttpKernel\HttpKernel->handle(object(Request), 1, true)
(vendor/symfony/http-kernel/Kernel.php:201)
at Symfony\Component\HttpKernel\Kernel->handle(object(Request))
(public/index.php:25)
我可以以某種方式將 preUpdate 的行為應用到其他地方嗎?
這是formMapper:
$formMapper
->tab("Information")
->add('email', TextType::class, [
'attr' => [
'readonly' => $emailDisabledState,
],
])
->add('password', RepeatedType::class, [
'type' => PasswordType::class,
'invalid_message' => 'The password fields must match.',
'options' => ['attr' => ['class' => 'password-field']],
'required' => false,
'first_options' => ['label' => 'Password'],
'second_options' => ['label' => 'Repeat Password'],
])
->add('isActive', BooleanType::class)
->add('roles', ChoiceType::class, [
'choices' => array_flip($flattendRoles),
'multiple' => true,
'expanded' => false,
])
->end()
->end()
->tab("Products")
->add("products", EntityType::class, [
'class' => Product::class,
'multiple' => true
])
->end()
->end();
非常感謝幫助
重復類型的聲明似乎很好。
您不必防止 preUpdate 中的錯誤。
您的實體中的參數是可選的嗎?
public function setPassword(?string $password): self
{
$this->password = $password;
return $this;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.