Pre_submit问题在Symfony3上保存数据

时间:2019-02-14 08:17:20

标签: php symfony symfony-3.4

我有一家公司,其中有一个徽标字段。我在编辑页面中的想法是,如果在编辑表单中,该字段为空,则保留我们以前在数据库上拥有的徽标,因为这是必填字段。

我的想法是获取以前要提交的表单数据,并检查该字段是否为空以从数据库中获取数据以对其进行更新。我使用了eventListener,但是在提交数据时,获取null不会改变。对于这个symfony版本,我几乎是新手,但我无法做到这一点。你可以帮帮我吗。谢谢

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

例如,如果先前要保存的图像名称为company122121.jpg,而数据的编辑表单为空,则将company122121.jpg保留在数据库中。但是结果始终为空。我已经在侦听器上检查了$ event-> getData(),数据是正确的,但是当我在isSubmitted()之后获取数据时,该数据为空。

Result with dump listener and image after submit

2 个答案:

答案 0 :(得分:0)

根据官方文档: https://symfony.com/doc/current/controller/upload_file.html

  

创建表单以编辑已保留的项目时,文件表单   类型仍然需要File实例。现在作为永久实体   仅包含相对文件路径,您首先必须串联   配置的上传路径和存储的文件名并创建一个新的   文件类别:

std::vector<int> my_vector {1,3,3,7};

for(auto [i, my_element] : en::enumerate(my_vector))
{
    // do stuff
}

所以我认为您应该添加

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

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

之后

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

答案 1 :(得分:0)

我还建议通过“事件事件订阅者”中包含的服务来处理图像上传。

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

参考: 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);
        }
    }
}