编辑表单中的Symfony文件上载

时间:2017-01-05 14:58:07

标签: php file-upload symfony symfony-forms

我有以下用户实体

/**
 * @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;
    }
}

这是我的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'
        ]);
    }
}

这是我控制器中的代码

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
    ]);
}

如果我上传一个新文件,它可以正常工作,但是如果我将输入字段提交为空,它会更改为我不想要的数据库中的NULL值,我想要的是,如果用户之前已经上传了图片并在下次将其留空,只是不要更改数据库中图片的值。

注意:我不确定这条信息是否有帮助,但我使用Ajax和FormData提交表单,我省略了部分代码以保持简单。

我在这里缺少什么?

1 个答案:

答案 0 :(得分:2)

无论文件是否已上传,都会调用

struct element elements[118] = { {"hydrogen", "H", 1, 1}, {"helium", "He", 2, 4}, ... etc }; - 尝试在上面的if语句中移动它:

$em->persist($data)

因此,只有在文件上传后才会保留对象。

,如果在该表单上还有其他字段可以更改且表单总是需要持久化,可以将数据设置为之前的当前用户图片值 >你的if语句:

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
}