简体   繁体   中英

Multiple Upload Symfony2

I'm beginning with Symfony and I'm stuck with multiple upload.

I can upload just one file and I try to modify this code for multiple upload.

Here's my error :

Expected argument of type "Symfony\Component\HttpFoundation\File\UploadedFile", "array" given

Here's my code :

ImageArticleType:

$builder
        ->add('file', 'file', array('label' => 'Choisir mes images', 'multiple'=> true))
    ;

And my Entity ImageArticle.php

<?php

namespace AD\PlatformBundle\Entity;

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

/**
 * ImageArticle
 *
 * @ORM\Table()
 * @ORM\Entity()
 * @ORM\HasLifecycleCallbacks
 */
class ImageArticle
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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

    /**
     * @var File
     *  
     * @Assert\File(
     *     maxSize = "1M",
     *     mimeTypes = {
     *          "image/jpeg", 
     *          "image/gif", 
     *          "image/png", 
     *          },
     *     maxSizeMessage = "La taille maximum du fichier doit etre inférieur ou égale à 1MB. Pour reduire sa taille vous pouvez utiliser le site : compressjpeg.com",
     *     mimeTypesMessage = "Seulement les fichiers .jpeg / .gif /.png sont acceptés"
     * )
     */
    private $file;

    private $tempFileName;

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

    public function setFile(UploadedFile $file)
    {

        $this->file = $file;

        if (null !== $this->url)
        {
            $this->tempFileName = $this->url;
            $this->url=null;
            $this->alt=null;
        }
    }
    /**
     * Get id
     *
     * @return integer
     */
    public function getId()
    {
        return $this->id;
    }

    /**
     * Set url
     *
     * @param string $url
     *
     * @return ImageArticle
     */
    public function setUrl($url)
    {
        $this->url = $url;

        return $this;
    }

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

    /**
     * Set alt
     *
     * @param string $alt
     *
     * @return ImageArticle
     */
    public function setAlt($alt)
    {
        $this->alt = $alt;

        return $this;
    }

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

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function preUpload()
    {
        if (null === $this->file)
        {
            return;
        }


        //On add un extension pour le fichier.
        $this->url = $this->file->guessExtension();
        //Le alt est le nom du fichier du client.
        $this->alt=  $this->file->getClientOriginalName();

    }

    /**
     * 
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     * 
     */
    public function upload()
    {
        if(null=== $this->file)
        {
            return;
        }

        //Si ancien fichier on supprime
        if(null !== $this->tempFileName)
        {
            $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->tempFileName;
            if (file_exists($oldFile))
            {
                unlink($oldFile);
            }
        }

        //On deplace
        $this->file->move
        (
            $this->getUploadRootDir(),
            $this->id.'.'.$this->url    
        );
    }

    /**
     *@ORM\PreRemove()
     */
    public function preRemoveUpload()
    {
        $this->tempFileName = $this->getUploadRootDir().'/'.$this->id.'.'.$this->url;
    }

    /**
     * 
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if(file_exists($this->tempFileName))
        {
            unlink($this->tempFileName);
        }
    }
    public function getUploadDir()
    {
        return 'upload/img/';
    }

    protected function getUploadRootDir()
    {
        return __DIR__.'/../../../../web/'.$this->getUploadDir();
    }

    public function __toString()
    {
        return $this->getUploadDir().$this->id.'.'.$this->getUrl();
    }

    /**
     * Set source
     *
     * @param string $source
     *
     * @return Image
     */
}

I was thinking about a simple foreach loop but it doesn't work...

Uploading files with multiple option can be a little bit tricky. With multiple = false option your $file property in your entity class will return single UploadedFile instance, with multiple = true it returns array of UploadedFile instances when you call $entity->getFile() . That's why you have to implement the upload process manually, on form submission, in your action, without lifecycle callbacks. Like this:

Action:

....
$image = new ImageArticle();

$form = $this->createForm('YOUR_FORM', $image);
$form->handleRequest($request);

if ($form->isValid()) {
    ...

    foreach ($image->getFile() as $uploadedFile) {
        $image = new ImageArticle();
        $image
            // setters go here
        ;

        // Upload process go here

        $image->setFile(null);
    }

    $this->get('doctrine.orm.entity_manager')->flush();

    ....
}

Here is a screenshot from my project: 在此输入图像描述

Something like that ?

public function newArticleAction(Request $request)
{
   $article = new Article();
   $article->setUser($this->getUser());

   $imageArticle = new ImageArticle();

   $form = $this->get('form.factory')->create(new \AD\PlatformBundle\Form\ArticleType(), $article, $image); 
    if($form->handleRequest($request)->isValid())
    {
        foreach($imageArticle->getFile() as $imageArticle)
        {
            $imageArticle = new ImageArticle();

            $imageArticle->setAlt($imageArticle->getAlt());
            $imageArticle->setUrl($imageArticle->getUrl());
            $imageArticle->setFile($imageArticle->getFile());

            $imageArticle->preRemoveUpload();
            $imageArticle->preUpload();
            $imageArticle->upload();

        }
        $em = $this->getDoctrine()->getManager();
        $em->persist($article);
        $em->flush();

        $request->getSession()->getFlashBag()->add('notice', 'Article publié ! :)');
        return $this->redirect($this->generateUrl('va_platform_blog'));
    }
    return $this->render('ADPlatformBundle:Cars:newarticle.html.twig', array(
        'form' =>$form->createView(),
    ));
}

Is your images are save in the article entity or another (I'll make changes when I get your answer) ?

I have made some little changes to your code. I'm not sure about all the code but I think this should work

public function newArticleAction(Request $request)
{
   $article = new Article();
   $images = new ImageArticle();

   $form = $this->get('form.factory')->create(ArticleType::class, $article, $images);
   $form->handleRequest($request);

   if($form->isValid())
   {
       $article->setUser($this->getUser());
       // other article fields, if needed

       foreach($images->getFile() as $image)
       {
           $images->setAlt($image->getAlt());
           $images->setUrl($image->getUrl());
           $images->setFile($image->getFile());

           $images->preRemoveUpload();
           $images->preUpload();
           $images->upload();
       }

       $em = $this->getDoctrine()->getManager();
       $em->persist($article);
       $em->flush();

       $request->getSession()->getFlashBag()->add('notice', 'Article publié ! :)');

       return $this->redirect($this->generateUrl('va_platform_blog'));
    }

    return $this->render('ADPlatformBundle:Cars:newarticle.html.twig', [
        'form' => $form->createView(),
    ]);
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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