Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Multi files upload in Symfony2?

I spent nearly 2 months on this issue : How to handle multi files upload on Symfony2? I tried many Bundles, many solutions, but nothing really works.

So, I would like to know if it's possible to give me some help.

Here's my Entity File :

<?php

namespace Monitoring\IdocBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Doctrine\Common\Collections\ArrayCollection;

/**
 * Sap3a13Feuil1
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Monitoring\IdocBundle\Entity\Sap3a13Feuil1Repository")
 */
class Sap3a13Feuil1
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var string
     *
     * @ORM\Column(name="Delivery", type="string", length=255)
     */
    private $delivery;

    /**
     * @var string
     *
     * @ORM\Column(name="Statut", type="string", length=255)
     */
    private $statut;

    /**
     * @var string
     *
     * @ORM\Column(name="IDocNumber", type="string", length=255)
     */
    private $iDocNumber;

    /**
     * @var DateTime $createDate
     *
     * @ORM\Column(name="CreateDate", type="datetime")
     */
    private $createDate;

    /**
     * @var DateTime $createHours
     *
     * @ORM\Column(name="CreateHours", type="datetime")
     */
    private $createHours;

    /**
     * @var string
     *
     * @ORM\Column(name="Text_status", type="string", length=255)
     */
    private $textStatus;

    /**
     * @var string
     *
     * @ORM\Column(name="Param1", type="string", length=255)
     */
    private $param1;

    /**
     * @var string
     *
     * @ORM\Column(name="Param2", type="string", length=255)
     */
    private $param2;

    /**
     * @var string
     *
     * @ORM\Column(name="URL", type="string", length=255)
     */
    private $url;

    /**
     * @Assert\File(maxSize="6000000000000")
     */
    public $file = array();


    public function __construct()
    {
        $this->createDate  = new \Datetime;
        $this->createHours = new \Datetime;
    }

    // GETTERS AND SETTERS

    public function setFile(UploadedFile $file)
    {
        $this->file = $file;
    }

    /**
     * Get url
     *
     * @return string 
     */
    public function getUrl()
    {
        return $this->url;
    }

    public function getFile()
    {
        return $this->file;
    }

    public function upload()
    {
    // Si jamais il n'y a pas de fichier (champ facultatif)
        if (null === $this->file) {
            return;
        }

                // On garde le nom original du fichier de l'internaute
                $name = $this->file->getClientOriginalName();

                // On déplace le fichier envoyé dans le répertoire de notre choix
                $this->file->move($this->getUploadRootDir(), $name);

                // On sauvegarde le nom de fichier dans notre attribut $url
                $this->url = $name;

                unset($this->file);
    }

    public function getUploadDir()
    {
        // On retourne le chemin relatif vers l'image pour un navigateur
        return 'uploads/img';
    }

    protected function getUploadRootDir()
    {
        // On retourne le chemin relatif vers l'image pour notre code PHP
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }


}

And there is my form in my FileType:

    <?php

namespace Monitoring\IdocBundle\Form;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;

class Sap3a13Feuil1Type extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {

        $builder
            ->add('file', 'file', array(
                'data_class' => null,
                'label' => 'Fichiers',
                'attr' => array(
                    'multiple' => true,
                    ))
            )
            ;
    }

    /**
     * @param OptionsResolverInterface $resolver
     */
    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Monitoring\IdocBundle\Entity\Sap3a13Feuil1'
        ));
    }

    /**
     * @return string
     */
    public function getName()
    {
        return 'monitoring_idocbundle_sap3a13feuil1';
    }
}

My controller :

    <?php

namespace Monitoring\IdocBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use Monitoring\IdocBundle\Entity\Sap3a13Feuil1;
use Monitoring\IdocBundle\Form\Sap3a13Feuil1Type;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class UploadController extends Controller{

    public function uploadAction()
    {

        // On crée un objet Sap3a13Feuil1
        $Sap3a13Feuil1 = new Sap3a13Feuil1();

        $file = [$Sap3a13Feuil1];var_dump($file);

        // On ajoute les champs de l'entité que l'on veut à notre formulaire
        $form = $this->createForm(new Sap3a13Feuil1Type, $Sap3a13Feuil1);

        //on récupère la requête
        $request = $this->get('request');
        //on vérifie que la requête est de type POST
        if ($request->getMethod() == 'POST'){


            //on fait le lien entre la requête et le formulaire
            //a partir de maintenant, la variable $Sap3a13Feuil1
            //contiendra les valeurs entrées
            $form->bind($request);

            //on vérifie que les valeurs entrées sont correctes
            if($form->isValid()){

                    $Sap3a13Feuil1->upload();
                    //si le formulaire est valide
                    //on enregistre l'objet dans la BDD
                    //$em = $this->getDoctrine()->getManager();
                    //$em->persist($Sap3a13Feuil1);
                    //$em->flush();

                //on redirige vers la page habituelle
                return $this->redirect($this->generateUrl('monitoring_idoc_flow'));
            }
        }

    return $this->render('MonitoringIdocBundle:Default:upload.html.twig', array(
        'form' => $form->createView(),
        ));
    }


    /**public function uploadAction()
    {
        $request = $this->getRequest();


        $editId = $this->getRequest()->get('editId');

        if(!preg_match('/^\d+$/', $editId))
        {
            $editId = sprintf('%09d', mt_rand(0,1999999999));
            if($Sap3a13Feuil1->getId())
            {
                $this->get('punk_ave.file_uploader')->syncFiles(
                    array('from_folder' => 'attachments/'.$Sap3a13Feuil1->getId(),
                        'to_folder' => 'tmp/attachments/'.$editId,
                        'create_to_folder' => true));
            }
        }

        $fileUploader = $this->get('punk_ave.file_uploader');
        $fileUploader->syncFiles(
            array('from_folder' => '/tmp/attachments/'.$editId,
                'remove_from_folder' => true,
                'create_to_folder' =>true));
    }**/
} 

And, finally, my view (where I call my form) :

<tr>
    <td><form action="{{ path('monitoring_idoc_flow') }}" method="post" {{ form_enctype(form) }} {{ form_widget(form) }} </td>
    <td><p><input type="submit"/></p></td>
        </form>
</tr> 

If anyone could help me, it would be very nice. Thank you !

like image 466
Creed Avatar asked Nov 02 '22 05:11

Creed


1 Answers

If it were me (and I have done this), I would use collections. So, all you need to do is create a generic FileUploadType form, with the buildForm looking like this...

public function buildForm(FormBuilderInterface $builder, array $options) {
    $builder->add('field_name', 'file', array(
        'label' => 'Some Label',
    )
}

Then, I personally had another entity to keep track of all my files uploaded, so I can check ownership etc. See this article in the documentation, it's pretty straight forward.

From there on, in the form you want to upload from, you just declare a field as such (in the formBuilder method:

//...
->add('your_field_name_here', 'collection', array(
    'type' => new FileUploadType(),
    'allow_add' => true, //etc etc
    //...
)

and that should work if your main entity has a OneToMany relationship with the new "file" entity you created.

EDIT Oh, if you DO use my method of adding another entity to keep track of your files, don't forget to do this in the FileUploadType:

public function setDefaultOptions(OptionsResolverInterface $resolver) {
    $resolver->setDefaults(array(
        'data_class' => 'Path\To\Your\Bundle\Entity\FileUpload'
    ));
}
like image 97
iLikeBreakfast Avatar answered Nov 04 '22 06:11

iLikeBreakfast