dongzhui4927 2015-07-19 18:36
浏览 48
已采纳

如何在Symfony 2中集成多个实体

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';

    }

}
  • 写回答

2条回答 默认 最新

  • doucong7963 2015-08-20 23:16
    关注

    I finally solved it!

    I used the collection field and followed this cookbook: http://symfony.com/doc/current/cookbook/form/form_collections.html

    I was able to have only one form (well, technicly two form since one is a collection, but whatever) and it is used for both creating a project and editting one. The only thing that change is the way I create the form in controller:

    <?php
    
    ...
    
    public function addAction(Request $request)
      {
        //Create new project
        $nouveauProjet = new Projet();
    
        $descriptionFr = new ProjetInt();
        $descriptionEn = new ProjetInt();
    
        $nouveauProjet->addDescription($descriptionFr);
        $nouveauProjet->addDescription($descriptionEn);
        $descriptionFr->setProjet($nouveauProjet);
        $descriptionEn->setProjet($nouveauProjet);
    
        $form=$this->createForm(new ProjetType(), $nouveauProjet);
    
        $form->handleRequest($request);
    
        if($form->isValid())
        {
          //Save the project
          ...
        }
    
        return $this->render('AdminBundle::ajoutProjet.html.twig',array(
                                          'form'=>$form->createView()
                                        ));
      }
    
      public function editAction($id, Request $request)
      {
        $project=$this->getDoctrine()->getRepository('PublicBundle:Projet')->findOneById($id);
    
        $form=$this->createForm(new ProjetType(), $projet);
    
        $form->handleRequest($request);
    
        if($form->isValid())
        {
          $em=$this->getDoctrine()->getManager();
          $em->flush();
    
          $this->get('session')->getFlashBag()->add('confirmation', 'The project was editted');
        }
    
        return $this->render('AdminBundle::modifierProjet.html.twig',array(
                                                                            'form'=>$form->createView(),
                                                                        ));
      }
    
    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥100 Jenkins自动化部署—悬赏100元
  • ¥15 关于#python#的问题:求帮写python代码
  • ¥20 MATLAB画图图形出现上下震荡的线条
  • ¥15 关于#windows#的问题:怎么用WIN 11系统的电脑 克隆WIN NT3.51-4.0系统的硬盘
  • ¥15 perl MISA分析p3_in脚本出错
  • ¥15 k8s部署jupyterlab,jupyterlab保存不了文件
  • ¥15 ubuntu虚拟机打包apk错误
  • ¥199 rust编程架构设计的方案 有偿
  • ¥15 回答4f系统的像差计算
  • ¥15 java如何提取出pdf里的文字?