Could not load type “file” in Symfony3

前端 未结 2 1433
自闭症患者
自闭症患者 2020-12-21 21:24

I am building form with multiple image upload and I can\'t find solution for problem that is mentioned in title. To help me with that I included VichUploaderBundle

R

相关标签:
2条回答
  • 2020-12-21 21:47

    As I promised, I'm providing you a little example of how you can create a multiple-upload form & how to get the data from the form and move it from the temp directory to your desired one, and save the path in the database.

    1) Create the Entity class.

    <?php
    namespace AppBundle\Entity;
    use Doctrine\ORM\Mapping as ORM;
    /**
     * @ORM\Table(name="galleries")
     * @ORM\Entity(repositoryClass="AppBundle\Repository\GalleryRepository")
     */
    class Gallery
    {
        /**
         * @ORM\Column(name="id", type="integer")
         * @ORM\Id
         * @ORM\GeneratedValue(strategy="AUTO")
         */
        private $id;
    
        /**
         * @ORM\Column(name="path", type="string", length=255)
         */
        private $path;
    
        // getter for $id, setter & getter for $path here
    }
    

    2) Create the Form.

    use Symfony\Component\Form\Extension\Core\Type\FileType;
    //...
    $builder->add('path', FileType::class, [
        'data_class' => null,
        'multiple' => true,
        'label' => false
    ]);
    

    3) The upload will be done using an upload service like here is stated. So set the directory you want your file to go in config.yml (don't set this parameter in parameters.yml because this file is ignored by git, if you push the project).

    #app/config/config.yml
    parameters:
        upload_dir: '%kernel.root_dir%/../web/upload'
    

    4) Declare the service.

    #app/config/services.yml
    services:
        app.img_upload:
            class: AppBundle\Services\FileUpload
            arguments: ['%upload_dir%']
    

    5) Create the service.

    #AppBundle\Services\FileUpload.php
    
    namespace AppBundle\Services;
    
    use Symfony\Component\HttpFoundation\File\UploadedFile;
    
    class FileUpload
    {
        private $targetDir;
    
        public function __construct($targetDir)
        {
            $this->targetDir = $targetDir;
        }
    
        public function upload(UploadedFile $file)
        {
            $file_name = $file->getClientOriginalName();
    
            empty($file_name) ? $file_name = md5(uniqid()).'.'.$file->guessExtension() : $file_name = $file->getClientOriginalName();
    
            $file->move($this->targetDir, $file_name);
    
            return $file_name;
        }
    }
    

    6) Create the whole logic in the controller.

    #AppBundle/Controller/DefaultController.php
    
    namespace AppBundle\Controller;
    //...
    use AppBundle\Entity\Gallery;
    use AppBundle\Form\GalleryType;
    //class...
    
    /**
     * @Route("/", name="homepage")
     */
    public function indexAction(Request $request)
    {
        $gallery = new Gallery();
        $form = $this->createForm(GalleryType::class, $gallery, [
            'action'=>$this->generateUrl('homepage'),
            'method'=>'POST'
        ]);
    
        $form->handleRequest($request);
    
        if($form->isSubmitted() && $form->isValid()) {
            $paths = $form->get('path')->getData();
    
            foreach ($paths as $path){
                $img = $this->get('app.img_upload')->upload($path);
    
                $em = $this->getDoctrine()->getConnection();
                $stmt = $em->prepare('INSERT INTO galleries SET path=?');
                $stmt->execute([$img]);
    
                // THIS IS THE PROBLEM I ENCOUNTER! I COULDN'T USE NORMAL DOCTRINE WAY TO SAVE EACH IMAGE PATH INTO THE DB. KNOW THE FIX? POST IT HERE PLEASE!
                // $em = $this->getDoctrine()->getManager();
                // $em->persist($gallery);
                // $em->flush();
    
                //LE: I've found the "bug": you need to instantiate, for each $path, a new $gallery object, then set the data for it, + persist & flush.
            }
    
            $this->addFlash('success', 'The image(s) were successfully uploaded');
    
            return $this->redirectToRoute('homepage');
        }
    
        return $this->render('default/index.html.twig', ['form'=>$form->createView()]);
    }
    

    7) Finally, display the form.

    # app/Resource/views/default/index.html.twig
    {% extends 'base.html.twig' %}
    
    {% block body %}
    {{ form_start(form) }}
        {{ form_row(form.path) }}
        <button type="submit" title="Upload an image">
            Upload
        </button>
    {{ form_end(form) }}
    {% endblock %}
    
    0 讨论(0)
  • 2020-12-21 22:07

    Here is how you should add it to your form:

    use Symfony\Component\Form\Extension\Core\Type\FileType;
    
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
         $builder->add('image', FileType::class);
    }
    

    In Symfony 3 a form type is always passed by its fully qualified class name

    0 讨论(0)
提交回复
热议问题