Как предоставить SF / Sonata RepeatedType (pw) на пользователя / редактировать для администраторов - PullRequest
0 голосов
/ 29 апреля 2020

мы работаем с symfony 4.4 и используем сонаты для администрирования нашей организации. мы реализовали довольно легкое управление пользователями, а также имеем возможность добавлять продукты пользователю во второй вкладке на странице редактирования пользователя. поэтому теперь администратор хочет назначить продукты пользователю, но проблема в том, что поле пароля не допускает такое поведение. Сначала поле пароля было обязательным, но установка его в false не помогает вообще, потому что тогда поле просто передается пустым.

поэтому решение, которое я попробовал, заключается в использовании функции preUpdate в моем классе администратора для предотвращения этой ошибки.

    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.

таким образом, данная ошибка:

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

без предварительного обновления, имеющего какой-либо эффект.

Какое здесь решение?

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) 

Могу ли я каким-либо образом применить поведение preUpdate где-нибудь еще?

и вот формаMapper:

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

помощь очень ценится

1 Ответ

0 голосов
/ 02 мая 2020

Объявление повторного типа кажется хорошим.

Вам не нужно предотвращать ошибку в preUpdate.

Является ли параметр необязательным в вашей сущности?

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

        return $this;
    }
...