vendredi 10 avril 2015

Upload multiple images using symfony without extra bundles

I have a problem when I try to upload more than one image to the database. I've read the symfony docs, and I could upload one image per time. I also read the


http://ift.tt/YnVJYl


Up to now, I fully understand the process of uploading ONE IMAGE, but what happens when you need to upload more than one image? Here's my situation, I have a Store entity and a StorePhoto entity, a Store contains a OneToMany relation with StorePhoto(variable commerce_photos), (I'm developing some sort of image gallery for a store.) The idea is to upload more than one picture at a time, I mean select more than one file and upload them. Here's what I've done


My Store entity



<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;

/**
* @ORM\Entity
* @ORM\Table(name="store")
*
*/

class Store{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

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

/**
* @ORM\OneToOne(targetEntity="StorePhoto")
*/
protected $photo;

/**
* @ORM\OneToMany(targetEntity="StorePhoto", mappedBy="store_photo")
*/
protected $commerce_photos;

public function __construct(){
$this->commerce_photos = new ArrayCollection();
}


/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Set name
*
* @param string $name
* @return Store
*/
public function setName($name)
{
$this->name = $name;

return $this;
}

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

/**
* Add commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
* @return Store
*/
public function addCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos[] = $commercePhotos;

return $this;
}

/**
* Remove commerce_photos
*
* @param \AppBundle\Entity\StorePhoto $commercePhotos
*/
public function removeCommercePhotos(\AppBundle\Entity\StorePhoto $commercePhotos)
{
$this->commerce_photos->removeElement($commercePhotos);
}

/**
* Get commerce_photos
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCommercePhotos()
{
return $this->commerce_photos;
}
}


My StorePhoto entity



<?php

namespace AppBundle\Entity;

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


/**
* @ORM\Entity
* @ORM\Table(name="store_photo")
*/

class StorePhoto{

/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;

/**
* @ORM\Column(type="string", length=255)
*/
protected $imageName;

/**
* @ORM\Column(type="string", length=255,nullable=false)
*/
protected $path;

/**
* @ORM\ManyToOne(targetEntity="Store", inversedBy="commerce_photos")
*/
protected $store_photo;

/**
* @Assert\Image
(mimeTypes = {"image/jpg", "image/jpeg", "image/gif", "image/png"},
mimeTypesMessage = "Solo acepta imagenes en formato JPG, GIF ou PNG.",
maxSize="5000k")
*/
private $imageFile;

/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}

/**
* Get file.
*
* @return UploadedFile
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* Sets file.
*
* @param UploadedFile $imageFile
*/
public function setImageFile(UploadedFile $file = null)
{
$this->imageFile = $file;
}
/**
* Set imageName
*
* @param string $imageName
* @return StorePhoto
*/
public function setImageName($imageName)
{
$this->imageName = $imageName;

return $this;
}

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

/**
* Set store_photo
*
* @param \AppBundle\Entity\Store $storePhoto
* @return StorePhoto
*/
public function setStorePhoto(\AppBundle\Entity\Store $storePhoto = null)
{
$this->store_photo = $storePhoto;

return $this;
}

/**
* Get store_photo
*
* @return \AppBundle\Entity\Store
*/
public function getStorePhoto()
{
return $this->store_photo;
}
public function getAbsolutePath()
{
return null === $this->path
? null
: $this->getUploadRootDir().'/'.$this->path;
}
public function getWebPath()
{
return null === $this->path
? null
: $this->getUploadDir().'/'.$this->path;
}
protected function getUploadRootDir()
{
//the absolute directory where uploaded documents should be saved
return __DIR__.'/../../../../web/images'.$this->getUploadDir();

}
protected function getUploadDir()
{
//get rid of the __DIR__ so it doesn't screw up
//when displaying uploaded doc/image in the view
return 'uploads/documents';

}
public function upload()
{
//the file property can be empty if the field is not required

if(null === $this->getImageFile())
{
return;
}
//use the original file name here but you should
//sanitaze it at least to avoid any security issues

//move takes the target directory and then the target filename to move to.
$this->getImageFile()->move(
$this->getUploadRootDir(), $this->getImageFile()->getClientOriginalName()
);

//set the path property to the filename where you've saved the file
$this->path = $this->getImageFile()->getClientOriginalName();
//clean up the file property as you won't need it anymore...
$this->imageFile = null;

}

}


My controller



<?php

namespace AppBundle\Controller;

use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route;
use Symfony\Bundle\FrameworkBundle\Controller\Controller;
use AppBundle\Forms\Type\FileUploadType;
use Symfony\Component\HttpFoundation\Request;
use AppBundle\Entity\StorePhoto;
use AppBundle\Entity\Store;
use Symfony\Component\HttpFoundation\Response;
use AppBundle\Forms\Type\MultipleFileUploadType;


class DefaultController extends Controller
{

public function multipleFileUploadAction(Request $request)
{
$store = new Store();

$store->setName('Test01');

$store->addCommercePhotos(new StorePhoto());

$form = $this->createForm(new MultipleFileUploadType(),$store);

$form->handleRequest($request);

if($form->isValid())
{
$em = $this->getDoctrine()->getManager();

$em->persist($store);

$em->flush();

return new Response('200 OK...');
}

return $this->render('Forms/FileUpload.html.twig',array('form'=>$form->createView()));


}
}


My Forms now, FileUploadType and MultipleFileUploadType



<?php
namespace AppBundle\Forms\Type;

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

class FileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('imageName', 'text');
$builder->add('imageFile', 'file',
array('multiple'=>'multiple'));
// $builder->add('Save', 'submit');

}
public function getName()
{
return "storePhoto";

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\StorePhoto',
));


}
}

?>

<?php
namespace AppBundle\Forms\Type;

use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use AppBundle\Forms\Type\FileUploadType;

class MultipleFileUploadType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder->add('name','text');
$builder->add('commerce_photos', 'collection',array(
'type' => new FileUploadType()));
$builder->add('Save', 'submit');

}
public function getName()
{
return "MultipleFileUpload";

}

public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\Store',
));
}
}

?>


That's all the code, I don't know if I'm missing something here. What I need to do is to display the dialog, select several images and then save them. In this case, In the controller I wrote this line



$store = new Store();

$store->setName('Test01');

$store->addCommercePhotos(new StorePhoto());


In this case, when I render the form, It shows me a dialog and only allows me to choose one file. If I delete the third line, addCommerce... It only shows me the label commercePhotos.


Thanks in advance!


Aucun commentaire:

Enregistrer un commentaire