Bonjour,

Pour un projet, j'essaye de faire un système d'annonce pour vente de voiture. Mon prblème est l'upload d'images pour chaque annonce (ManyToOne). J'ai réussi à ecrire les entitées avec les relation cependant mon problème reste l'upload des fichier puis la persistance de sont url dans la base de donnée. Voici mes entitées, leurs formulaires et le controlleur.

Avec ce code, les entitées Images uploadée (contenues dans l'entité Advert) n'ont pas ni ID, ni alt, ni url. L'attribut file lui contient bien une instance de UploadedFile.

Image

/**
 * Image
 *
 * @ORM\Table(name="Images")
 * @ORM\Entity(repositoryClass="HBY\AppBundle\Entity\ImageRepository")
 */
class Image
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="HBY\AppBundle\Entity\Advert", inversedBy="images")
     * @ORM\JoinColumn(nullable=false)
     */
    private $advert;

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

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

    private $file;

    private $filename;

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

    /**
     * Set url
     *
     * @param string $url
     * @return Image
     */
    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 Image
     */
    public function setAlt($alt)
    {
        $this->alt = $alt;

        return $this;
    }

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

    /**
     * Set advert
     *
     * @param \HBY\AppBundle\Entity\Advert $advert
     * @return Image
     */
    public function setAdvert( $advert)
    {
        $this->advert = $advert;
        $this->advert->addImage($this);
        return $this;
    }

    /**
     * Get advert
     *
     * @return \HBY\AppBundle\Entity\Advert 
     */
    public function getAdvert()
    {
        return $this->advert;
    }

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

    public function setFile(UploadedFile $file)
    {
        $this->file = $file;
        if (null !== $this->url) {
            $this->filename = $this->url;
            $this->url = null;
            $this->alt = null;
        }
    }

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

    /**
     * @ORM\PostPersist()
     * @ORM\PostUpdate()
     */
    public function upload()
    {
        if (null === $this->file) {
            return;
        }
        if (null !== $this->filename) {
            $oldFile = $this->getUploadRootDir().'/'.$this->id.'.'.$this->filename;
            if (file_exists($oldFile)) {
                unlink($oldFile);
            }
        }
        $this->file->move(
            $this->getUploadRootDir(),
            $this->id.'.'.$this->url
        );
    }

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

    /**
     * @ORM\PostRemove()
     */
    public function removeUpload()
    {
        if (file_exists($this->filename)) {
            unlink($this->filename);
        }
    }

    public function getUploadDir()
    {
        return 'uploads/images';
    }

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

    public function getWebPath()
    {
        return $this->getUploadDir().'/'.$this->getId().'.'.$this->getUrl();
    }
}

ImageType

class ImageType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('file', 'file')
        ;
    }

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

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

Advert

/**
 * Advert
 *
 * @ORM\Table(name="Adverts")
 * @ORM\Entity(repositoryClass="HBY\AppBundle\Entity\AdvertRepository")
 */
class Advert
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

    /**
     * @var string
     *
     * @ORM\Column(name="price", type="decimal")
     */
    private $price;

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

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="release_date", type="date")
     */
    private $releaseDate;

    /**
     * @var integer
     *
     * @ORM\Column(name="mileage", type="integer")
     */
    private $mileage;

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

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

    /**
     * @var string
     *
     * @ORM\Column(name="description", type="text")
     */
    private $description;

    /**
     * @ORM\OneToMany(targetEntity="HBY\AppBundle\Entity\Image", mappedBy="advert", cascade={"persist", "remove"})
     */
    private $images;

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

    /**
     * @var boolean
     *
     * @ORM\Column(name="active", type="boolean")
     */
    private $active;

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

    /**
     * Set title
     *
     * @param string $title
     * @return Advert
     */
    public function setTitle($title)
    {
        $this->title = $title;

        return $this;
    }

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

    /**
     * Set price
     *
     * @param string $price
     * @return Advert
     */
    public function setPrice($price)
    {
        $this->price = $price;

        return $this;
    }

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

    /**
     * Set category
     *
     * @param string $category
     * @return Advert
     */
    public function setCategory($category)
    {
        $this->category = $category;

        return $this;
    }

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

    /**
     * Set releaseDate
     *
     * @param \DateTime $releaseDate
     * @return Advert
     */
    public function setReleaseDate($releaseDate)
    {
        $this->releaseDate = $releaseDate;

        return $this;
    }

    /**
     * Get releaseDate
     *
     * @return \DateTime 
     */
    public function getReleaseDate()
    {
        return $this->releaseDate;
    }

    /**
     * Set mileage
     *
     * @param integer $mileage
     * @return Advert
     */
    public function setMileage($mileage)
    {
        $this->mileage = $mileage;

        return $this;
    }

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

    /**
     * Set fuel
     *
     * @param string $fuel
     * @return Advert
     */
    public function setFuel($fuel)
    {
        $this->fuel = $fuel;

        return $this;
    }

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

    /**
     * Set gearbox
     *
     * @param string $gearbox
     * @return Advert
     */
    public function setGearbox($gearbox)
    {
        $this->gearbox = $gearbox;

        return $this;
    }

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

    /**
     * Set description
     *
     * @param string $description
     * @return Advert
     */
    public function setDescription($description)
    {
        $this->description = $description;

        return $this;
    }

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

    /**
     * Add images
     *
     * @param \HBY\AppBundle\Entity\Image $images
     * @return Advert
     */
    public function addImage(Image $images)
    {
        $this->images[] = $images;

        return $this;
    }

    /**
     * Remove images
     *
     * @param \HBY\AppBundle\Entity\Image $images
     */
    public function removeImage(Image $images)
    {
        $this->images->removeElement($images);
    }

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

    /**
     * Set created
     *
     * @param \DateTime $created
     * @return Advert
     */
    public function setCreated($created)
    {
        $this->created = $created;

        return $this;
    }

    /**
     * Get created
     *
     * @return \DateTime 
     */
    public function getCreated()
    {
        return $this->created;
    }

    /**
     * Set active
     *
     * @param boolean $active
     * @return Advert
     */
    public function setActive($active)
    {
        $this->active = $active;

        return $this;
    }

    /**
     * Get active
     *
     * @return boolean 
     */
    public function getActive()
    {
        return $this->active;
    }

    /**
     * Constructor
     */
    public function __construct()
    {
        $this->created = new \Datetime();
        $this->images = new ArrayCollection();
    }

    /**
     * @ORM\PrePersist()
     * @ORM\PreUpdate()
     */
    public function hydrateId(){
        foreach($this->images as $image){
            $image->setAdvert($this);
        }
    }
}

AdvertType

class AdvertType extends AbstractType
{
        /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('title', 'text')
            ->add('price', 'number')
            ->add('category', 'choice', array('choices' => array(
                'Voiture 5P' => 'Voiture 5P',
                'Voiture 3P' => 'Voiture 3P'))
            )
            ->add('releaseDate', 'date', array(
                'input'  => 'datetime',
                'widget' => 'choice',)
            )
            ->add('mileage', 'text')
            ->add('fuel', 'choice', array('choices'   => array(
                'Diesel' => 'Diesel',
                'Essence' => 'Essence',
                'Electrique' => 'Electrique',
                'Gaz' => 'Gaz'))
            )
            ->add('gearbox', 'choice', array('choices' => array(
                'Automatique' => 'Automatique',
                'Manuelle' => 'Manuelle'))
            )
            ->add('description', 'textarea')
            ->add('images', 'collection', array(
                'type'         => new ImageType(),
                'allow_add'    => true,
                'allow_delete' => true,
                'by_reference' => false
            ))
            ->add('enregistrer', 'submit')
        ;

        $builder->addEventListener(
            FormEvents::PRE_SET_DATA,
            function(FormEvent $event) {
                $advert = $event->getData();

                if (null === $advert) {
                    return;
                }

                if (!$advert->getActive() || null === $advert->getId()) {
                    $event->getForm()->add('active', 'checkbox', array('required' => false));
                } else {
                    $event->getForm()->remove('active');
                }
            }
        );
    }

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

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

Controller (createAction)

public function createAction(Request $request){
        $advert = new Advert();
        $form = $this->createForm(new AdvertType(), $advert, array(
            'action' => $this->generateUrl('admin_advert_create'),
            'method' => 'POST',
        ));

        if ($form->handleRequest($request)->isValid()) {
            $em = $this->getDoctrine()->getManager();
            $em->persist($advert);

            $em->flush();

            $request->getSession()->getFlashBag()->add('notice', 'Votre mannonce a bien été créée.');

            return $this->redirect($this->generateUrl('admin_adverts'));
        }
        return $this->render('HBYAdminBundle:Admin:create.html.twig', array('form' => $form->createView()));
    }

1 réponse


A mon avis il ne persirt pas l'image. Il faut le rajouter.

PS : Evite le urgent dans le titre c'est désagréable celon moi et cela ne donne vraiment pas envie de répondre. (en général j'ouvre meme pas le fil quand il y a ce genre de titre)