简体   繁体   English

如何在用户/编辑上为管理员提供 SF/Sonata RepeatedType (pw)

[英]How to provide SF/Sonata RepeatedType (pw) on User/edit for Admins

we are working with symfony 4.4 and use sonata for our entity administration.我们正在使用 symfony 4.4 并使用奏鸣曲进行实体管理。 we implemented a pretty lightweight usermanagement and also have the possibility to add products to a user in a second tab on the user edit page.我们实现了一个非常轻量级的用户管理,并且还可以在用户编辑页面的第二个选项卡中向用户添加产品。 so now the admin wants to assign products to a user but the problem is that the password field does not allow that behaviour.所以现在管理员想要将产品分配给用户,但问题是密码字段不允许这种行为。 first the password field was required, but setting it to false does not help at all because then the field just gets submitted empty.首先密码字段是必需的,但将其设置为 false 根本没有帮助,因为该字段只是被提交为空。

so a solution i tried is to use the preUpdate function within my admin class to prevent that error.所以我尝试的一个解决方案是在我的管理员 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;

}

so if the password is not empty - we take the given value and update the password.因此,如果密码不为空 - 我们采用给定的值并更新密码。 if the field is empty we use the existing password, so its no problem to just add products and update the user entity.如果该字段为空,我们使用现有密码,因此只需添加产品和更新用户实体就没有问题。

that would be nice but the triggering error comes before the preUpdate function could help.这很好,但触发错误出现在 preUpdate function 可以提供帮助之前。

so the given error is:所以给定的错误是:

Expected argument of type "string", "null" given at property path "password".

without the preUpdate taking any effect.没有 preUpdate 生效。

what would be the solution here?这里的解决方案是什么?

full stacktrace:完整的堆栈跟踪:

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) 

can i somehow apply the behaviour of the preUpdate somewhere else?我可以以某种方式将 preUpdate 的行为应用到其他地方吗?

and here is the formMapper:这是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();

help is much appreciated非常感谢帮助

Declaration of repeated type seems good.重复类型的声明似乎很好。

You shouldn't have to prevent error in preUpdate.您不必防止 preUpdate 中的错误。

Is parameter optional in your entity?您的实体中的参数是可选的吗?

    public function setPassword(?string $password): self
    {
        $this->password = $password;

        return $this;
    }

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM