Php Symfony2保存嵌入集合表单
我在保存嵌入的集合表单字段时遇到问题。假设我有一个程序,这个程序有很多层次。在我的表单类型中: ProgramType.phpPhp Symfony2保存嵌入集合表单,php,jquery,forms,symfony,Php,Jquery,Forms,Symfony,我在保存嵌入的集合表单字段时遇到问题。假设我有一个程序,这个程序有很多层次。在我的表单类型中: ProgramType.php <?php namespace Eifl\AdminBundle\Form\Type; use Symfony\Component\Form\AbstractType; use Symfony\Component\Form\FormBuilderInterface; use Symfony\Component\OptionsResolver\OptionsRe
<?php
namespace Eifl\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProgramType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id','text',array(
'label'=>'Program Code',
))
->add('program','text',array(
'label'=>'Program Name',
))
->add('levels','collection', array(
'type'=>new LevelType(),
'allow_add'=>true,
'allow_delete'=>true,
'by_reference' => false,
))
->add('save','submit', array(
'label'=>'Save',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Eifl\AdminBundle\Entity\Program',
));
}
public function getName()
{
return 'Program';
}
}
public function programAction(Request $request)
{
$program = new Program();
$level = new Level();
$program->getLevels()->add($level);
$newProgram = $this->createForm(new ProgramType(),$program);
$newProgram->handleRequest($request);
if($newProgram->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($program);
$em->flush();
return $this->redirect($this->generateUrl('eifl_admin_program'));
}
return $this->render('EiflAdminBundle:Default:program.html.twig',array("new_program_form"=>$newProgram->createView()));
}
<?php
namespace Eifl\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Program
*
* @ORM\Entity
* @ORM\Table(name="tbl_program")
*/
Class Program
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="string")
*/
protected $id;
/**
*@ORM\Column(name="program_name",type="string")
*/
public $program;
/**
* @ORM\OneToMany(targetEntity="Eifl\AdminBundle\Entity\Level", mappedBy="program", cascade={"remove","persist"})
*/
public $levels;
public function __construct(){
$this->levels = new ArrayCollection();
}
/**
* @param string $id
* @return string
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Add Level
*
* @param \Eifl\AdminBundle\Entity\Level $levels
* @return Program
*/
public function addLevels(\Eifl\AdminBundle\Entity\Level $level) {
$this->levels[] = $level;
$levels->setProgram($this);
return $this;
}
/**
* set levels
*
* @param \Doctrine\Common\Collections\ArrayCollection $levels
* @return levels
*/
public function setLevels(\Doctrine\Common\Collections\ArrayCollection $levels) {
foreach ($levels as $level) {
$level->setProgram($this);
}
$this->levels = $levels;
}
public function removeLevels(\Eifl\AdminBundle\Entity\Level $level)
{
$this->levels->removeElement($level);
}
/**
* @param string $program
* @return string
*/
public function setProgram($program)
{
$this->program = $program;
return $this;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getProgram()
{
return $this->program;
}
/**
* @return string
*/
public function getLevels()
{
return $this->levels;
}
}
<?php
namespace Eifl\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Level
*
* @ORM\Entity
* @ORM\Table(name="tbl_level")
*/
Class Level
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
*@ORM\Column(name="level",type="string")
*/
public $level;
/**
* @ORM\ManyToOne(targetEntity="Eifl\AdminBundle\Entity\Program", inversedBy="levels")
* @ORM\JoinColumn(name="program", referencedColumnName="id")
*/
public $program;
/**
* @param string $id
* @return string
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @param string $level
* @return string
*/
public function setLevel($level)
{
$this->level = $level;
return $this;
}
/**
* @param mixed $program
* @return string
*/
public function setProgram(\Eifl\AdminBundle\Entity\Program $program)
{
$this->program = $program;
return $this;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getLevel()
{
return $this->level;
}
/**
* @return string
*/
public function getProgram()
{
return $this->program;
}
}
更新
这是我的实体类
Program.php
<?php
namespace Eifl\AdminBundle\Form\Type;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
class ProgramType extends AbstractType
{
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('id','text',array(
'label'=>'Program Code',
))
->add('program','text',array(
'label'=>'Program Name',
))
->add('levels','collection', array(
'type'=>new LevelType(),
'allow_add'=>true,
'allow_delete'=>true,
'by_reference' => false,
))
->add('save','submit', array(
'label'=>'Save',
));
}
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'Eifl\AdminBundle\Entity\Program',
));
}
public function getName()
{
return 'Program';
}
}
public function programAction(Request $request)
{
$program = new Program();
$level = new Level();
$program->getLevels()->add($level);
$newProgram = $this->createForm(new ProgramType(),$program);
$newProgram->handleRequest($request);
if($newProgram->isValid()){
$em = $this->getDoctrine()->getManager();
$em->persist($program);
$em->flush();
return $this->redirect($this->generateUrl('eifl_admin_program'));
}
return $this->render('EiflAdminBundle:Default:program.html.twig',array("new_program_form"=>$newProgram->createView()));
}
<?php
namespace Eifl\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* Program
*
* @ORM\Entity
* @ORM\Table(name="tbl_program")
*/
Class Program
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="string")
*/
protected $id;
/**
*@ORM\Column(name="program_name",type="string")
*/
public $program;
/**
* @ORM\OneToMany(targetEntity="Eifl\AdminBundle\Entity\Level", mappedBy="program", cascade={"remove","persist"})
*/
public $levels;
public function __construct(){
$this->levels = new ArrayCollection();
}
/**
* @param string $id
* @return string
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* Add Level
*
* @param \Eifl\AdminBundle\Entity\Level $levels
* @return Program
*/
public function addLevels(\Eifl\AdminBundle\Entity\Level $level) {
$this->levels[] = $level;
$levels->setProgram($this);
return $this;
}
/**
* set levels
*
* @param \Doctrine\Common\Collections\ArrayCollection $levels
* @return levels
*/
public function setLevels(\Doctrine\Common\Collections\ArrayCollection $levels) {
foreach ($levels as $level) {
$level->setProgram($this);
}
$this->levels = $levels;
}
public function removeLevels(\Eifl\AdminBundle\Entity\Level $level)
{
$this->levels->removeElement($level);
}
/**
* @param string $program
* @return string
*/
public function setProgram($program)
{
$this->program = $program;
return $this;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getProgram()
{
return $this->program;
}
/**
* @return string
*/
public function getLevels()
{
return $this->levels;
}
}
<?php
namespace Eifl\AdminBundle\Entity;
use Doctrine\ORM\Mapping as ORM;
/**
* Level
*
* @ORM\Entity
* @ORM\Table(name="tbl_level")
*/
Class Level
{
/**
* @ORM\Id
* @ORM\Column(name="id", type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
/**
*@ORM\Column(name="level",type="string")
*/
public $level;
/**
* @ORM\ManyToOne(targetEntity="Eifl\AdminBundle\Entity\Program", inversedBy="levels")
* @ORM\JoinColumn(name="program", referencedColumnName="id")
*/
public $program;
/**
* @param string $id
* @return string
*/
public function setId($id)
{
$this->id = $id;
return $this;
}
/**
* @param string $level
* @return string
*/
public function setLevel($level)
{
$this->level = $level;
return $this;
}
/**
* @param mixed $program
* @return string
*/
public function setProgram(\Eifl\AdminBundle\Entity\Program $program)
{
$this->program = $program;
return $this;
}
/**
* @return mixed
*/
public function getId()
{
return $this->id;
}
/**
* @return string
*/
public function getLevel()
{
return $this->level;
}
/**
* @return string
*/
public function getProgram()
{
return $this->program;
}
}
检查是否将addLevel和setLevel放入程序实体中
/**
* Add Level
*
* @param \Eifl\AdminBundle\Entity\Level $levels
* @return Program
*/
public function addLevel(\Eifl\AdminBundle\Entity\Level $levels) {
$this->levels[] = $levles;
$level->setProgram($this);
return $this;
}
/**
* set levels
*
* @param \Doctrine\Common\Collections\ArrayCollection $levels
* @return levels
*/
public function setLevels(\Doctrine\Common\Collections\ArrayCollection $levels) {
foreach ($levles as $level) {
$level->setPogram($this);
}
$this->levels = $levels;
}
从控制器中删除此代码
$level = new Level();
$program->getLevels()->add($level);
实体程序中的getter和setter$级别混淆
制作:
public function addLevel(Level $level) { //without s
$this->levels[] = $level;
}
public function removeLevel(Level $level) //without s
{
$this->levels->removeElement($level);
}
public function getLevels()
{
return $this->levels;
}
删除其他public function setLevels、public function removeLevels等
正如Adene Choubi所说,$program->getLevels()->add($level)代码>也没有意义
我不知道这是不是唯一的麻烦,但从那开始。这对我有点帮助。我已经声明了addLevels
函数,但是我忘了在我的程序
实体中声明setLevels
函数。这有助于我保存与级别相关的程序名称。还有同样的问题,只保存第一个和最后一个级别,只保存在数据库中的两个级别。然后检查是否在级别类中声明setProgram方法检查我的更新。我已经声明了该方法。仍然不能接收超过2个级别。我是否需要做一个循环并检查有多少层形成了一个有值的字段?如果我必须这样做,我应该在哪里添加循环条件呢?你可以在setLevel中添加一个计数器,或者用count($form->getData()->getLevel())签入你的控制器,也许我在构建表单时犯了错误,因为当我count($form->getData()->getLevel())
时,它返回2
。我希望返回3
。如果我删除这些代码,我只能保存1级。也许我必须做一个循环,但我无法从字段中获得级别数。