I'm working on a form in Symfony 2 and I need some help. The form is use to modify information about a project. I got two entity, projet(a project) and projetInt(all the text that need to be internationalized). I made a ProjetType form and it works fine.
The probleme comes when I need to had the projetInt form inside de projet form. At first, I tried to use a collection field, but I ran into a weird error that I haven't solved yet (https://stackoverflow.com/questions/31397195/error-with-the-collection-field-in-form-in-symfony-2).
The thing is that what I would like to have is that the projetInt form be added twice inside the projet form since the text of my projet must be available in both french and english. An other thing is that I would like that this form be usable for my add projet action, because if I want to modify my project, I would just need to pass the project to the form since in both cases, either add or modify, the necessary field or exactly the same.
Here is what I got so far:
My projet entity:
<?php
namespace PublicBundle\Entity;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\ORM\Mapping as ORM;
use Symfony\Component\HttpFoundation\File\UploadedFile;
use Symfony\Component\Validator\Constraints as Assert;
/**
* Projet
*
* @ORM\Table(name="pt_projet");
* @ORM\Entity
* @ORM\Entity(repositoryClass="PublicBundle\Entity\ProjetDepot")
* @ORM\HasLifecycleCallbacks
*/
class Projet
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
//ID du projet
protected $id;
/**
* @ORM\OneToMany(targetEntity="ProjetInt", mappedBy="projet", orphanRemoval=true)
*/
protected $descriptions;
/**
* @ORM\Column(name="pro_img", type="string", length=64, unique=true)
*/
//Nom du fichier de l'image du projet
protected $image;
private $imageTemp;
/**
* @ORM\Column(name="pro_technologie_utilisee", type="text", length=200)
*/
//Text qui liste tout les technologies utilisées pour le projet
protected $technologie;
/**
* @ORM\Column(name="pro_annee", type="integer", length=4)
*/
//Année de réalisation du projet
protected $annee;
/**
* @ORM\ManyToOne(targetEntity="Type", inversedBy="projets")
* @ORM\JoinColumn(name="pro_type", referencedColumnName="id", nullable=false)
*/
//Clef étrangère du type de projet
//Le type de projet ne correspond pas à la catégore. Il peu être Unity, flash, image, vidéo, etc. Il permet de savoir quelle page charger pour pouvoir intégrer le projet dans le portfolio.
protected $type;
/**
* @ORM\Column(name="pro_fichier", type="string", length=64, unique=true)
*/
//Nom du fichier du projet
private $fichier;
private $fichierTemp;
/**
* @ORM\Column(name="pro_largeur", type="integer")
*/
//Largeur du projet
protected $largeur;
/**
* @ORM\Column(name="pro_hauteur", type="integer")
*/
//Hauteur du projet
protected $hauteur;
/**
* @ORM\ManyToMany(targetEntity="Categorie", cascade={"persist"})
*/
//La ou les catégories du projet
private $categories;
/**
* Constructor
*/
public function __construct()
{
$this->descriptions=new ArrayCollection();
$this->categories=new ArrayCollection();
}
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set image
*
* @param string $image
* @return Projet
*/
public function setImage($image)
{
$this->image = $image;
return $this;
}
/**
* Get image
*
* @return string
*/
public function getImage()
{
return $this->image;
}
/**
* Set technologie
*
* @param string $technologie
* @return Projet
*/
public function setTechnologie($technologie)
{
$this->technologie = $technologie;
return $this;
}
/**
* Get technologie
*
* @return string
*/
public function getTechnologie()
{
return $this->technologie;
}
/**
* Set annee
*
* @param integer $annee
* @return Projet
*/
public function setAnnee($annee)
{
$this->annee = $annee;
return $this;
}
/**
* Get annee
*
* @return integer
*/
public function getAnnee()
{
return $this->annee;
}
/**
* Set fichier
*
* @param string $fichier
* @return Projet
*/
public function setFichier($fichier)
{
$this->fichier = $fichier;
return $this;
}
/**
* Get fichier
*
* @return string
*/
public function getFichier()
{
return $this->fichier;
}
/**
* Set largeur
*
* @param integer $largeur
* @return Projet
*/
public function setLargeur($largeur)
{
$this->largeur = $largeur;
return $this;
}
/**
* Get largeur
*
* @return integer
*/
public function getLargeur()
{
return $this->largeur;
}
/**
* Set hauteur
*
* @param integer $hauteur
* @return Projet
*/
public function setHauteur($hauteur)
{
$this->hauteur = $hauteur;
return $this;
}
/**
* Get hauteur
*
* @return integer
*/
public function getHauteur()
{
return $this->hauteur;
}
/**
* Add descriptions
*
* @param \PublicBundle\Entity\ProjetInt $descriptions
* @return Projet
*/
public function addDescription(\PublicBundle\Entity\ProjetInt $descriptions)
{
$this->descriptions[] = $descriptions;
return $this;
}
/**
* Remove descriptions
*
* @param \PublicBundle\Entity\ProjetInt $descriptions
*/
public function removeDescription(\PublicBundle\Entity\ProjetInt $descriptions)
{
$this->descriptions->removeElement($descriptions);
}
/**
* Get descriptions
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getDescriptions()
{
return $this->descriptions;
}
/**
* Set type
*
* @param \PublicBundle\Entity\Type $type
* @return Projet
*/
public function setType(\PublicBundle\Entity\Type $type)
{
$this->type = $type;
return $this;
}
/**
* Get type
*
* @return \PublicBundle\Entity\Type
*/
public function getType()
{
return $this->type;
}
/**
* Add categories
*
* @param \PublicBundle\Entity\Categorie $categories
* @return Projet
*/
public function addCategory(\PublicBundle\Entity\Categorie $categories)
{
$this->categories[] = $categories;
return $this;
}
/**
* Remove categories
*
* @param \PublicBundle\Entity\Categorie $categories
*/
public function removeCategory(\PublicBundle\Entity\Categorie $categories)
{
$this->categories->removeElement($categories);
}
/**
* Get categories
*
* @return \Doctrine\Common\Collections\Collection
*/
public function getCategories()
{
return $this->categories;
}
/**
* @Assert\File(maxSize="6000000")
*/
private $fichierFile;
/**
* Sets fichier file.
*
* @param UploadedFile $fichierFile
*/
public function setFichierFile(UploadedFile $fichierFile = null)
{
$this->fichierFile = $fichierFile;
//Vérifi s'il y a déja un fichier de projet
if(isset($this->fichier))
{
//Stock l'ancien nom pour l'effacer après la mise à jour
$this->fichierTemp=$this->fichier;
$this->fichier=null;
}
else
{
$this->fichier='initial';
}
}
/**
* Get fichier file.
*
* @return UploadedFile
*/
public function getFichierFile()
{
return $this->fichierFile;
}
/**
* @Assert\File(maxSize="6000000")
*/
private $imageFile;
/**
* Sets image file.
*
* @param UploadedFile $imageFile
*/
public function setImageFile(UploadedFile $imageFile = null)
{
$this->imageFile = $imageFile;
//Vérifi s'il y a déja un fichier d'image
if(isset($this->image))
{
//Stock l'ancien nom pour l'effacer après la mise à jour
$this->imageTemp=$this->image;
$this->image=null;
}
else
{
$this->image='initial';
}
}
/**
* Get image file.
*
* @return UploadedFile
*/
public function getImageFile()
{
return $this->imageFile;
}
/**
* @ORM\PrePersist()
* @ORM\PreUpdate()
*/
public function preUpload()
{
//S'il y a un fichier pour le projet
if (null !== $this->getFichierFile())
{
//Génère un nom unique
$nomFichierProjet = sha1(uniqid(mt_rand(), true));
$this->fichier = $nomFichierProjet.'.'.$this->getFichierFile()->guessExtension();
}
//S'il y a un fichier pour l'image
if (null !== $this->getImageFile())
{
//Génère un nom unique
$nomFichierImage = sha1(uniqid(mt_rand(), true));
$this->image = $nomFichierImage.'.'.$this->getImageFile()->guessExtension();
}
}
/**
* @ORM\PostPersist()
* @ORM\PostUpdate()
*/
public function upload()
{
if (null !== $this->getFichierFile())
{
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->getFichierFile()->move($this->getUploadRootDirFichier(), $this->fichier);
//Vérifi s'il y a déja un fichier de projet
if (isset($this->fichierTemp)) {
//Efface l'ancien fichier du projet
unlink($this->getUploadRootDirFichier().'/'.$this->fichierTemp);
//Efface le chemin temporaire
$this->fichierTemp = null;
}
$this->fichierFile = null;
}
if (null !== $this->getImageFile())
{
// if there is an error when moving the file, an exception will
// be automatically thrown by move(). This will properly prevent
// the entity from being persisted to the database on error
$this->getImageFile()->move($this->getUploadRootDirImage(), $this->image);
//Vérifi s'il y a déja un fichier d'image
if (isset($this->imageTemp)) {
//Efface l'ancienne image du projet
unlink($this->getUploadRootDirImage().'/'.$this->imageTemp);
//Efface le chemin temporaire
$this->imageTemp = null;
}
$this->imageFile = null;
}
}
/**
* @ORM\PostRemove()
*/
public function removeUpload()
{
$fichierFile = $this->getAbsolutePathFichier();
if ($fichierFile) {
unlink($fichierFile);
}
$imageFile = $this->getAbsolutePathImage();
if ($imageFile) {
unlink($imageFile);
}
}
public function getAbsolutePathFichier()
{
return null === $this->fichier
? null
: $this->getUploadRootDirFichier().'/'.$this->fichier;
}
public function getWebPathFichier()
{
return null === $this->fichier
? null
: $this->getUploadDirFichier().'/'.$this->fichier;
}
public function getAbsolutePathImage()
{
return null === $this->image
? null
: $this->getUploadRootDirImage().'/'.$this->image;
}
public function getWebPathImage()
{
return null === $this->fichier
? null
: $this->getUploadDirImage().'/'.$this->image;
}
//Le chemin absolu du répertoire où le fichier du projet se trouve
protected function getUploadRootDirFichier()
{
return __DIR__.'/../../../web/'.$this->getUploadDirFichier();
}
//Le chemin absolu du répertoire où l'image du projet se trouve
protected function getUploadRootDirImage()
{
return __DIR__.'/../../../web/'.$this->getUploadDirImage();
}
protected function getUploadDirFichier()
{
return 'bundles/public/projets/'.$this->getType()->getNom();
}
protected function getUploadDirImage()
{
return 'bundles/public/projets/vignettes';
}
}
My projetInt entity:
<?php
namespace PublicBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Projet Inter
*
* @ORM\Table(name="pt_projet_int");
* @ORM\Entity
* @ORM\Entity(repositoryClass="PublicBundle\Entity\ProjetIntDepot")
*/
class ProjetInt
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
//ID du projet
protected $id;
/**
* @ORM\ManyToOne(targetEntity="Projet", inversedBy="descriptions")
* @ORM\JoinColumn(name="pro_id_CE", referencedColumnName="id", nullable=false)
*/
//Clef étrangère du projet associé
protected $projet;
/**
* @ORM\Column(name="pri_lang", type="string", length=2)
*/
//Langue de la carégorie
protected $langue;
/**
* @ORM\Column(name="pri_nom", type="string", length=30)
*/
//Nom du produit
protected $nom;
/**
* @ORM\Column(name="pri_description_cours", type="text",length=100)
*/
//Description cours du projet
protected $descriptionCours;
/**
* @ORM\Column(name="pri_description_complete", type="text",length=250)
*/
//Description complete du projet
protected $descriptionComplete;
/**
* @ORM\Column(name="pri_roles", type="string",length=60)
*/
//Roles joués dans la création du projet
protected $roles;
/**
* @ORM\Column(name="pri_aptitudes_developpees", type="string",length=200)
*/
//Aptitudes développées lors du projet
protected $aptitudesDeveloppees;
/**
* Get id
*
* @return integer
*/
public function getId()
{
return $this->id;
}
/**
* Set langue
*
* @param string $langue
* @return ProjetInt
*/
public function setLangue($langue)
{
$this->langue = $langue;
return $this;
}
/**
* Get langue
*
* @return string
*/
public function getLangue()
{
return $this->langue;
}
/**
* Set nom
*
* @param string $nom
* @return ProjetInt
*/
public function setNom($nom)
{
$this->nom = $nom;
return $this;
}
/**
* Get nom
*
* @return string
*/
public function getNom()
{
return $this->nom;
}
/**
* Set descriptionCours
*
* @param string $descriptionCours
* @return ProjetInt
*/
public function setDescriptionCours($descriptionCours)
{
$this->descriptionCours = $descriptionCours;
return $this;
}
/**
* Get descriptionCours
*
* @return string
*/
public function getDescriptionCours()
{
return $this->descriptionCours;
}
/**
* Set descriptionComplete
*
* @param string $descriptionComplete
* @return ProjetInt
*/
public function setDescriptionComplete($descriptionComplete)
{
$this->descriptionComplete = $descriptionComplete;
return $this;
}
/**
* Get descriptionComplete
*
* @return string
*/
public function getDescriptionComplete()
{
return $this->descriptionComplete;
}
/**
* Set roles
*
* @param string $roles
* @return ProjetInt
*/
public function setRoles($roles)
{
$this->roles = $roles;
return $this;
}
/**
* Get roles
*
* @return string
*/
public function getRoles()
{
return $this->roles;
}
/**
* Set aptitudesDeveloppees
*
* @param string $aptitudesDeveloppees
* @return ProjetInt
*/
public function setAptitudesDeveloppees($aptitudesDeveloppees)
{
$this->aptitudesDeveloppees = $aptitudesDeveloppees;
return $this;
}
/**
* Get aptitudesDeveloppees
*
* @return string
*/
public function getAptitudesDeveloppees()
{
return $this->aptitudesDeveloppees;
}
/**
* Set projetId
*
* @param \PublicBundle\Entity\Projet $projetId
* @return ProjetInt
*/
public function setProjetId(\PublicBundle\Entity\Projet $projetId)
{
$this->projetId = $projetId;
return $this;
}
/**
* Get projetId
*
* @return \PublicBundle\Entity\Projet
*/
public function getProjetId()
{
return $this->projetId;
}
/**
* Set projet
*
* @param \PublicBundle\Entity\Projet $projet
* @return ProjetInt
*/
public function setProjet(\PublicBundle\Entity\Projet $projet)
{
$this->projet = $projet;
return $this;
}
/**
* Get projet
*
* @return \PublicBundle\Entity\Projet
*/
public function getProjet()
{
return $this->projet;
}
}
My forms:
projet form:
<?php
namespace AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
Class ProjetType extends AbstractType
{
public function buildForm(FormBuilderInterface $constructeur, array $options)
{
$constructeur
->add('imageFile')
//Doesn't work
/*->add('descriptions', 'collection', array(
'type' => new ProjetIntType(),
'by_reference'=>false,
'allow_add'=>true,
'allow_delete'=>true,
))*/
->add('technologie', 'text')
->add('annee', 'text', array('label'=>'année'))
->add('type', 'entity', [
'class'=>'PublicBundle\Entity\Type',
'property'=>'nom',
'required'=>true,
])
->add('fichierFile')
->add('largeur', 'text')
->add('hauteur', 'text')
->add('categories', 'entity', [
'label'=>'catégorie',
'class'=>'PublicBundle\Entity\Categorie',
'property'=>'tag',
'required'=>true,
'multiple'=>true,
'expanded'=>true,
])
->add('Modifier', 'submit');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'PublicBundle\Entity\Projet',
));
}
public function getName()
{
return 'projet';
}
}
projetInt form:
<?php
namespace AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
Class ProjetIntType extends AbstractType
{
public function buildForm(FormBuilderInterface $constructeur, array $options)
{
$constructeur
->add('langue', 'text')
->add('nom', 'text')
->add('descriptionCours', 'text')
->add('descriptionComplete', 'text')
->add('roles', 'text')
->add('aptitudesDeveloppees', 'text');
}
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'PublicBundle\Entity\ProjetInt',
));
}
public function getName()
{
return 'projetInt';
}
}