Pre_submit问题在Symfony3上保存数据

I have a crud of Companies where there is a field for the logo. My idea in the edit page, is that if in the edit form, the field is empty, keeping the logo that we had previously on the DB because this is a field required.

My idea was to get the data of the form previously to be submited and check if the field is empty to get the data from the database to update it with it. I have used eventListener, but when the data is submitted, it doesn't change getting null. I am almost new with this symfony version but I am not able to do this. Could you help me. Thanks,

/**
    * @Route("/admin/companies/edit/{id}", name="edit_company")
    * Method({"GET", "POST"})
    */
    public function editCompany(Request $request, $id){

        $company = new Company();
        $company = $this->getDoctrine()->getRepository(Company::class)->find($id);      

        $form = $this->createFormBuilder($company)
            ->add('name', TextType::class, array('attr' => array('class' => 'form-control')))
            ->add('description', TextAreaType::class, array('attr' => array('class' => 'form-control summernote')))
            ->add('telephone', TextType::class, array('attr' => array('class' => 'form-control')))
            ->add('city', TextType::class, array('attr' => array('class' => 'form-control')))
            ->add('web', UrlType::class, array('attr' => array('class' => 'form-control')))
            ->add('image', FileType::class, array('data_class' => null, 'label' => false, 'required' => false, 'attr' => array('class' => 'form-control d-none')))            
            ->add('save', SubmitType::class, ['label' => 'Edit Company', 'attr' => array('class' => 'btn btn-success p-2 mt-5')])`enter code here`
            ->addEventListener(FormEvents::PRE_SUBMIT, function(FormEvent $event) {
                $data = $event->getData();
                $form = $event->getForm();
                $image = $data['image'];
                if ($image == null){
                    $company_tmp = $this->getDoctrine()->getRepository(Company::class)->find($form->getData()->getId());
                    $data['image'] = $company_tmp->getImage();           
                    $event->setData($data);
                }               

            })          
            ->getForm();

        $form->handleRequest($request);


        if ( ($form->isSubmitted()) && ( $form->isValid() ) ){          

            $company = $form->getData();

            $file = $form->get('image')->getData();

            if ($file !== null){
                $fileName = 'company-'.$this->generateUniqueFileName().'.'.$file->guessExtension();                         
                // Move the file to the directory where brochures are stored
                try {
                    $moved = $file->move( $this->get('kernel')->getProjectDir() . '/public/uploads', $fileName );
                } catch (FileException $e) {
                   throw new HttpNotFoundException("Page not found");
                }
                $company->setImage($fileName);
            }

            $entityManager= $this->getDoctrine()->getManager();     
            $entityManager->flush();
            $flashbag = $this->get('session')->getFlashBag();           
            $flashbag->add("success", "Company Edited Correctly");  

            return $this->redirectToRoute('companies_list');
        }

        return $this->render('admin/edit_company.html.twig', 
            array(
                'form' => $form->createView(),
                'company' => $company,
            )
        );
    }

For example if the name of the image previously to save is company122121.jpg and the edit form the data is empty, keep the company122121.jpg on the db. But the result is always null. I have checked the $event->getData() on the listener and the data is correct but when I get the data after isSubmitted() the data is null.

Result with dump listener and image after submit

From the official documentation : https://symfony.com/doc/current/controller/upload_file.html

When creating a form to edit an already persisted item, the file form type still expects a File instance. As the persisted entity now contains only the relative file path, you first have to concatenate the configured upload path with the stored filename and create a new File class:

use Symfony\Component\HttpFoundation\File\File;
// ...

$product->setBrochure(
    new File($this->getParameter('brochures_directory').'/'.$product->getBrochure())
);

So I think you should add

$company->setImage(new File($pathToYourImage));

after

$company = $this->getDoctrine()->getRepository(Company::class)->find($id);      

I would also suggest to handle the image upload via a Service which is included through a Doctrine Event Subscriber.

I also save Images as Media Objects to the database which contain the file name of the uploaded images which is resolved properly via a postLoad listener.

Reference: Doctrine Event Subscriber File Upload Service

class UploadHandler
{
    /** @var string */
    private $fileDirectory;

    /**
     * FileUploader constructor.
     *
     * @param string $fileDirectory
     */
    public function __construct(
        string $fileDirectory
    ) {
        $this->fileDirectory = $fileDirectory;
    }

    /**
     * Move the file to the upload directory.
     *
     * @param UploadedFile $file
     *
     * @return string
     */
    public function upload(UploadedFile $file) {
        $fileName = md5(uniqid() . '.' . $file->guessExtension());

        $file->move($this->getFileDirectory(), $fileName);

        return $fileName;
    }

    /**
     * @return string
     */
    public function getFileDirectory(): string {
        return $this->fileDirectory;
    }
}
class UploadEventSubscriber
{
    /**
     * @var FileUploader
     */
    private $uploader;

    /**
     * UploadEventSubscriber constructor.
     * @param FileUploader $uploader
     */
    public function __construct(
        FileUploader $uploader
    )
    {
        $this->uploader = $uploader;
    }

    /**
     * Returns an array of events this subscriber wants to listen to.
     *
     * @return string[]
     */
    public function getSubscribedEvents()
    {
        return [
            'prePersist',
            'preUpdate',
            'postLoad'
        ];
    }

    /**
     * Pre-Persist method for Media.
     *
     * @param LifecycleEventArgs $args
     */
    public function prePersist(LifecycleEventArgs $args) {
        /** @var Media $entity */
        $entity = $args->getEntity();

        if (!$this->validInstance($entity)) {
            return;
        }

        $this->uploadFile($entity);
    }

    /**
     * Pre-Update method for Media.
     *
     * @param LifecycleEventArgs $args
     */
    public function preUpdate(LifecycleEventArgs $args) {
        /** @var Media $entity */
        $entity = $args->getEntity();

        if (!$this->validInstance($entity)) {
            return;
        }

        $this->uploadFile($entity);
    }

    /**
     * Post-Load method for Media
     *
     * @param LifecycleEventArgs $args
     */
    public function postLoad(LifecycleEventArgs $args) {
        /** @var Media $entity */
        $entity = $args->getEntity();

        if (!$this->validInstance($entity)) {
            return;
        }

        $fileName = $entity->getImage();
        if($fileName) {
            $entity->setImage(new File($this->uploader->getFileDirectory() . '/' . $fileName));
        }
    }

    /**
     * Check if a valid entity is given.
     *
     * @param object $entity
     * @return bool
     */
    private function validInstance($entity)
    {
        return $entity instanceof Media;
    }

    /**
     * Upload the file
     * @param Media $entity
     */
    private function uploadFile(Media $entity)
    {
        $file = $entity->getImage();

        if($file instanceof UploadedFile) {
            $fileName = $this->uploader->upload($file);
            $entity->setImage($fileName);
        }
    }
}