简体   繁体   English

Pre_submit问题在Symfony3上保存数据

[英]Pre_submit problem saving data on 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. 我使用了eventListener,但是在提交数据时,获取null不会改变。 I am almost new with this symfony version but I am not able to do this. 对于这个symfony版本,我几乎是新手,但我无法做到这一点。 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. 例如,如果先前要保存的图像的名称为company122121.jpg,而数据的编辑表单为空,则将db122.jpg保留在数据库上。 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. 我已经在侦听器上检查了$ event-> getData(),数据是正确的,但是当我在isSubmitted()之后获取数据时,该数据为空。

Result with dump listener and image after submit 提交后带有转储侦听器和图像的结果

From the official documentation : https://symfony.com/doc/current/controller/upload_file.html 从官方文档中: 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. 创建表单以编辑已经保存的项目时,文件表单类型仍然需要File实例。 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: 由于持久实体现在仅包含相对文件路径,因此您首先必须将配置的上传路径与存储的文件名连接起来,并创建一个新的File类:

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. 我还将图像作为媒体对象保存到数据库,其中包含上载图像的文件名,可以通过postLoad侦听器正确解析。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM