Symfony File Upload In Edit Form

丶灬走出姿态 提交于 2020-01-05 05:00:33

问题


I have the following User Entity

/**
 * @ORM\Entity
 */
class User
{
    /**
     * @ORM\Column(type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=100, nullable=false)
     */
    private $name;

    /**
     * @ORM\Column(type="string", name="picture", nullable=true)
     * @Assert\Image
     * @Assert\File(maxSize = "2M")
     */
    private $picture;

    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set name
     *
     * @param string $name
     * @return User
     */
    public function setName($name)
    {
        $this->name = $name;
        return $this;
    }

    /**
     * Get name
     *
     * @return string
     */
    public function getName()
    {
        return $this->name;
    }

    public function setPicture($file)
    {
        $this->picture = $file;
        return $this;
    }

    public function getPicture()
    {
        return $this->picture;
    }
}

And here is my FormType

class UserType extends AbstractType
{
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder->add('name', TextType::class, [
            'label' => 'Name *',
            'attr' => [
                'class' => 'form-control placeholder-height'
            ],
            'label_attr' => [
                'class' => 'col-md-2 professional-attr'
            ],
            'constraints' => [
                new Assert\NotBlank(),
                new Assert\Length(['min' => 3, 'max' => 50])
            ]
        ]);

        $builder->add('picture', FileType::class, [
            'label' => 'Profile Picture',
            'attr' => [
                'class' => 'form-control filestyle',
                'data-iconName' => 'glyphicon glyphicon-camera',
                'data-buttonText' => null,
                'accept' => 'image/*'
            ],
            'label_attr' => [
                'class' => 'col-md-2 professional-attr'
            ],
            'data_class' => null
        ]);

        $builder->add('confirm', SubmitType::class, [
            'label' => 'SUBMIT',
            'attr' => [
                'class' => 'submit'
            ]
        ]);
    }

    public function setDefaultOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults([
            'data_class' => 'UserBundle:User'
        ]);
    }
}

And here is the code in my controller

public function professionalEditAction(Request $request)
{
    $em = $this->get('doctrine.orm.entity_manager');
    $user = $em->getRepository('UserBundle:User')->findOneBy(['id' => $request->get('id')]);
    if (!$user) {
        throw $this->createNotFoundException('Invalid user or user does not exist');
    }
    $form = $this->createForm(Form\ProfessionalType::class, $user, [
        'method' => 'POST',
        'attr' => [
            'class' => 'form-horizontal',
            'novalidate' => 'novalidate',
            'accept' => 'image/*'
        ]
    ]);
    $form->handleRequest($request);
    $response = [];
    $response['params'] = [];
    if($form->isSubmitted() && $request->isXmlHttpRequest() && !$form->isValid()) {
        $data = $form->getData();
        foreach ($form as $child) {
            if (!$child->isValid()) {
                $response['status'] = 'error';
                $response['next_action'] = 'fix_error';
                $response['params'] = [];
                foreach ($child->getErrors() as $error) {
                    $response['errors'][$child->getName()][] = $error->getMessage();
                }
            }
        }
        return new JsonResponse($response);
    }
    if ($form->isSubmitted() && $form->isValid()) {
        $data = $form->getData();
        $file = $user->getPicture();
        if ($file instanceof UploadedFile) {
            $fileName = md5(uniqid()).'.'.$file->guessExtension();
            $file->move(
                $this->getParameter('profile.picture.attachment.dir'),
                $fileName
            );
            $data->setPicture($fileName);
        }
        $em->persist($data);
        $em->flush();
        $request->getSession()->getFlashBag()->add('success', 'User created successfully!');
        return $this->redirect($this->generateUrl('admin_professional_create'));
    }
    return $this->render('UserBundle:Admin:professional.edit.html.twig', [
        'form' => $form->createView(),
        'user' => $user
    ]);
}

It works perfectly if I upload a new file, but if I submit the input field empty, It changes to NULL value in DB which I do not want, what I want is, if user has previously uploaded the picture and leave it empty next time, just do not change the value of picture in the DB.

Note: I am not sure if this piece of Information helps, but I am submitting the form using Ajax and FormData, I have omitted part of the code to keep it simple.

What am I missing here?


回答1:


$em->persist($data) is being called whether the file has been uploaded or not - try moving it within the if statement above it:

if ($file instanceof UploadedFile) {
     $fileName = md5(uniqid()).'.'.$file->guessExtension();
     $file->move(
        $this->getParameter('profile.picture.attachment.dir'),
        $fileName
    );
    $data->setPicture($fileName);
    $em->persist($data); // Place here
}

So that will only persist the object if a file has been uploaded.

Or, if there are other fields that can be changed on that form and the form always needs persisting regardless, can you set the data to the current user picture value before your if statement:

$file = $user->getPicture();
$data->setPicture($file); // Store the current value from the DB before overwriting below
if ($file instanceof UploadedFile) {
     $fileName = md5(uniqid()).'.'.$file->guessExtension();
     $file->move(
        $this->getParameter('profile.picture.attachment.dir'),
        $fileName
    );
    $data->setPicture($fileName);
}
$em->persist($data); // Leave here in original place


来源:https://stackoverflow.com/questions/41488108/symfony-file-upload-in-edit-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!