如何保存文件而不点击提交按钮?Symfony 6.0.2

q3aa0525  于 2022-11-16  发布在  其他
关注(0)|答案(1)|浏览(124)

需要类型为“string”的参数,在属性路径“password”处给定“null”。

我不明白为什么在提交表单时会出现此错误。我想通过在密码输入中添加**'empty_data' =〉''**来确保不再出现此问题,但它没有解决此问题。
注:我给了“d-none”类密码输入和保存按钮,因为由于onChange属性,我希望直接发送文件时,它已经上传。
edit.html.twig

{{ form_start(form)  }}
    {{ form_widget(form.photo, {'attr' : {'onChange' : 'this.form.submit();'}} ) }}
    {{ form_widget(form.password.first, {'attr' : {'class' : 'd-none'}}) }}
    {{ form_widget(form.password.second, {'attr' : {'class' : 'd-none'}}) }}
    {{ form_widget(form.save, {'attr' : {'class' : 'd-none'}}) }}
{{ form_end(form) }}

UserType.php

<?php

namespace App\Form;

use App\Entity\User;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type\FileType;
use Symfony\Component\Form\Extension\Core\Type\SubmitType;
use Symfony\Component\Form\Extension\Core\Type\PasswordType;
use Symfony\Component\Form\Extension\Core\Type\RepeatedType;

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options): void
    {
        $builder
            ->add('password', PasswordType::class, [
                'mapped' => false,
                'empty_data' => ''
            ])
            ->add('password', RepeatedType::class, [
                'type' => PasswordType::class,
                'invalid_message' => 'Les deux mots de passe doivent être identiques.',
                'options' => ['attr' => ['class' => 'password-field']],
                'required' => true,
                'first_options'  => ['label' => 'Password'],
                'second_options' => ['label' => 'Repeat Password'],
                'empty_data' => ''
            ])
            ->add('photo', FileType::class, [
                'mapped' => false,
            ])
            ->add('save', SubmitType::class, [
                'attr' => ['class' => 'save'],
            ])
        ;
    }

    public function configureOptions(OptionsResolver $resolver): void
    {
        $resolver->setDefaults([
            'data_class' => User::class,
            'translation_domain' => 'forms'
        ]);
    }
}

SecurityController.php

<?php

namespace App\Controller;

use App\Form\UserType;
use App\Repository\UserRepository;
use Doctrine\ORM\EntityManagerInterface;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\String\Slugger\SluggerInterface;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\Security\Http\Authentication\AuthenticationUtils;

class SecurityController extends AbstractController
{
    #[Route(path: '/login', name: 'login')]
    public function login(AuthenticationUtils $authenticationUtils): Response
    {
        // if ($this->getUser()) {
        //     return $this->redirectToRoute('target_path');
        // }

        // get the login error if there is one
        $error = $authenticationUtils->getLastAuthenticationError();
        // last username entered by the user
        $lastUsername = $authenticationUtils->getLastUsername();
            
        return $this->render('security/login.html.twig', ['last_username' => $lastUsername, 'error' => $error]);
    }

    #[Route('/profile', name: 'profile')]
    public function addPhoto(
        Request $request,
        UserRepository $userRepository,
        SluggerInterface $sluggerInterface,
        EntityManagerInterface $entityManagerInterface
    ){
        $connected = $this->getUser();
        $useremail = $connected->getUserIdentifier();
        $user = $userRepository->findOneBy(['email' => $useremail]);

        $userform = $this->createForm(UserType::class, $user);
        $userform->handleRequest($request);

        if ($userform->isSubmitted() && $userform->isValid()) {
            $imagefile = $userform->get('photo')->getData();

            if ($imagefile){
                $originalFileName = pathinfo($imagefile->getClientOriginalName(), PATHINFO_FILENAME);
                $safeFileName = $sluggerInterface->slug($originalFileName);
                $newFileName = $safeFileName . '-' . uniqid() . '.' . $imagefile->guessExtension();
    
                $imagefile->move(
                    $this->getParameter('images_directory'),
                    $newFileName
                );
    
                $user->setPhoto($newFileName);
            }

            $entityManagerInterface->persist($user);
            $entityManagerInterface->flush();
            return $this->redirectToRoute('login');
        }

        return $this->renderForm('security/login.html.twig', [
            'user' => $user,
            'form' => $userform,
        ]);
    }

    #[Route(path: '/logout', name: 'logout')]
    public function logout(): void
    {
        throw new \LogicException('This method can be blank - it will be intercepted by the logout key on your firewall.');
    }
}
5t7ly7z5

5t7ly7z51#

我认为“问题”是在User::class中,而不是在SecurityController.php或其他地方。更准确地说,是在您的User-entity的setPassword()方法中。
我假设setter只需要****string

/**
 * @param string $password
 */
public function setPassword(string $password)
{
    $this->password = $password;
}

因为你没有显示password-field,它保持为空,它变成NULL,但是你的setPassword()只需要字符串。
因此,您可以更改setter以接受stringnull这两种类型

/**
 * @param string|null $password
 */
public function setPassword(?string $password = null)
{
    $this->password = $password;
}

作为一种选择,你也可以禁用你的密码字段。你需要在两个字段上使用“setRendered()”来去掉表单标签。

{{ form_start(form)  }}
    {{ form_widget(form.photo, {'attr' : {'onChange' : 'this.form.submit();'}} ) }}
    {{ form_widget(form.password.first, {disabled: true, attr: { class: 'd-none' }} ) }}
    {% do form.password.first.setRendered %}
    {{ form_widget(form.password.second, {disabled: true, attr: { class: 'd-none' }} ) }}
    {% do form.password.second.setRendered %}
    {{ form_widget(form.save, {'attr' : {'class' : 'd-none'}}) }}
{{ form_end(form) }}

但这不是一个理想的解决方案!我会重新考虑UserType::class(可能是两种不同的形式。一种有密码字段,另一种没有。)否则,您必须将密码字段设置为可选。

//somewhere in your UserType::class

$builder->add('password', RepeatedType::class, [ 
 // your other options
 'required' => false,
]);

相关问题