Symfony2:集合类型形式和多对多

时间:2015-06-16 13:08:01

标签: symfony doctrine-orm symfony-forms

我有3个实体,一个作为参考连接表(多对多)和其他字段。我想要实现的是从Placement表单中嵌入(PlacementTypeReference)表单。集合表单的数量必须与placementType数据库表中的行数完全相同。 这是实体:

展示位置

<?php

namespace AppBundle\Entity;

use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\ArrayCollection;
use AppBundle\Entity\PlacementTypeReference;

/**
 * Placement
 *
 * @ORM\Table(name="placement")
 * @ORM\Entity(repositoryClass="AppBundle\Entity\PlacementRepository")
 * @ORM\HasLifecycleCallbacks()
 */
class Placement
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\Column(name="crm_id", type="integer", nullable=true)
     */
    private $crm_id = null;

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

    /**
     * @var float
     *
     * @ORM\Column(name="default_price", type="float", nullable=true)
     */
    private $defaultPrice;

    /**
     * @var integer
     *
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Site", inversedBy="placements")
     */
    private $site;

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

    /**
     * @ORM\Column(name="default_rotations", type="integer", nullable=true)
     */
    private $defaultRotations = null;

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

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

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

    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\PlacementTypeReference", mappedBy="placement", cascade={"remove"})
     */
    private $placements;


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

    }

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

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

        return $this;
    }

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

    /**
     * Set defaultPrice
     *
     * @param float $defaultPrice
     * @return Placement
     */
    public function setDefaultPrice($defaultPrice)
    {
        $this->defaultPrice = $defaultPrice;

        return $this;
    }

    /**
     * Get defaultPrice
     *
     * @return float 
     */
    public function getDefaultPrice()
    {
        return $this->defaultPrice;
    }


    /**
     * @return int
     */
    public function getSite()
    {
        return $this->site;
    }

    /**
     * @param int $site
     */
    public function setSite($site)
    {
        $this->site = $site;
    }


    /**
     * @return \DateTime
     */
    public function getCreatedAt()
    {
        return $this->createdAt;
    }

    /**
     * @param \DateTime $createdAt
     */
    public function setCreatedAt($createdAt)
    {
        $this->createdAt = $createdAt;
    }

    /**
     * @return \DateTime
     */
    public function getModifiedAt()
    {
        return $this->modifiedAt;
    }

    /**
     * @param \DateTime $modifiedAt
     */
    public function setModifiedAt($modifiedAt)
    {
        $this->modifiedAt = $modifiedAt;
    }

    /**
     * @ORM\PrePersist
     * @ORM\PreUpdate
     */
    public function updatedTimestamps()
    {
        $this->setModifiedAt(new \DateTime(date('Y-m-d H:i:s')));

        if ($this->getCreatedAt() == null) {
            $this->setCreatedAt(new \DateTime(date('Y-m-d H:i:s')));
        }
    }

    /**
     * @param boolean $isActive
     */
    public function setIsActive($isActive)
    {
        $this->isActive = $isActive;
    }


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

    public function __toString()
    {
        return $this->name;
    }

    /**
     * @return string
     */
    public function getPaymentType()
    {
        return $this->payment_type;
    }

    /**
     * @param string $payment_type
     */
    public function setPaymentType($payment_type)
    {
        $this->payment_type = $payment_type;
    }

    /**
     * @return mixed
     */
    public function getCrmId()
    {
        return $this->crm_id;
    }

    /**
     * @param mixed $crm_id
     */
    public function setCrmId($crm_id)
    {
        $this->crm_id = $crm_id;
    }



    /**
     * @return mixed
     */
    public function getDefaultRotations()
    {
        return $this->defaultRotations;
    }

    /**
     * @param mixed $defaultRotations
     */
    public function setDefaultRotations($defaultRotations)
    {
        $this->defaultRotations = $defaultRotations;
    }

    /**
     * @return ArrayCollection
     */
    public function getPlacements()
    {
        return $this->placements->toArray();
    }

    public function addPlacement(PlacementTypeReference $placement)
    {
        if(!$this->placements->contains($placement))
        {
            $this->placements->add($placement);
            $placement->setPlacement($this);
        }
    }

    public function removePlacement(PlacementTypeReference $placement)
    {
        if($this->placements->contains($placement))
        {
            $this->placements->removeElement($placement);
            $placement->setPlacement(null);
        }
    }



}

PlacementType

<?php

namespace AppBundle\Entity;

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

/**
 * PlacementType
 *
 * @ORM\Table(name="placement_type")
 * @ORM\Entity
 */
class PlacementType
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

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

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


    /**
     * @ORM\OneToMany(targetEntity="AppBundle\Entity\PlacementTypeReference", mappedBy="placementType", cascade={"remove"})
     */
    private $placementTypes;

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

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

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

        return $this;
    }

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

    /**
     * Set dimension
     *
     * @param string $dimension
     * @return PlacementType
     */
    public function setDimension($dimension)
    {
        $this->dimension = $dimension;

        return $this;
    }

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

    public function getPlacementTypes()
    {
        return $this->placementTypes->toArray();
    }

    public function addPlacementType(PlacementTypeReference $placementType)
    {
        if(!$this->placementTypes->contains($placementType))
        {
            $this->placementTypes->add($placementType);
            $placementType->setPlacementType($this);
        }

        return $this;
    }

    public function removePlacementType(PlacementTypeReference $placementType)
    {
        if($this->placementTypes->contains($placementType))
        {
            $this->placementTypes->removeElement($placementType);
            $placementType->setPlacementType(null);
        }
        return $this;
    }



    public function __toString()
    {
        return $this->name;
    }



}

PlacementTypeReference 这将是一个连接表

<?php

namespace AppBundle\Entity;

use AppBundle\Entity\Placement;
use AppBundle\Entity\PlacementType;
use Doctrine\ORM\Mapping as ORM;

/**
 * PlacementTypeReference
 *
 * @ORM\Table(name="placement_type_reference")
 * @ORM\Entity
 */
class PlacementTypeReference
{
    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\Placement", inversedBy="placements")
     * @ORM\JoinColumn(name="placement_id", referencedColumnName="id", nullable=FALSE)
     */
    private $placement;

    /**
     * @ORM\ManyToOne(targetEntity="AppBundle\Entity\PlacementType", inversedBy="placementTypes")
     * @ORM\JoinColumn(name="placementType_id", referencedColumnName="id", nullable=FALSE)
     */
    private $placementType;

    /**
     * @var float
     *
     * @ORM\Column(name="coefficient", type="float")
     */
    private $coefficient = 1;



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

    /**
     * Set placement
     *
     * @param Placement $placement
     * @return PlacementTypeReference
     */
    public function setPlacement(Placement $placement = null)
    {
        if($this->placement !== null)
        {
            $this->placement->removePlacement($this);
        }

        if($placement !== null)
        {
            $placement->addPlacement($this);
        }

        $this->placement = $placement;

        return $this;
    }

    /**
     * Get placement
     *
     * @return Placement
     */
    public function getPlacement()
    {
        return $this->placement;
    }

    /**
     * Set placementType
     *
     * @param PlacementType $placementTypeId
     * @return PlacementTypeReference
     */
    public function setPlacementType(PlacementType $placementType = null)
    {
        if($this->placementType !== null)
        {
            $this->placementType->removePlacementType($this);
        }

        if($placementType !== null)
        {
            $placementType->addPlacementType($this);
        }

        $this->placementType = $placementType;

        return $this;
    }

    /**
     * Get placementType
     *
     * @return PlacementType
     */
    public function getPlacementType()
    {
        return $this->placementType;
    }

    /**
     * Set coefficient
     *
     * @param float $coefficient
     * @return PlacementTypeReference
     */
    public function setCoefficient($coefficient)
    {
        $this->coefficient = $coefficient;

        return $this;
    }

    /**
     * Get coefficient
     *
     * @return float 
     */
    public function getCoefficient()
    {
        return $this->coefficient;
    }
}

我正在尝试构建一个表单,我可以在其中嵌入PlacementTypeReferenceType表单的集合,表单数量由PlacementType表中的行数和预先填充的placementType id确定。

以下是展示位置的类型: 的 PlacementType

<?php

namespace AppBundle\Form\Type;

use Doctrine\ORM\EntityManager;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Doctrine\ORM\EntityRepository;
use AppBundle\Form\Type\PlacementTypeReferenceType;


class PlacementType extends AbstractType
{
    private $em;

    public function __construct($em)
    {
        $this->em = $em;
    }
    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        $builder
            ->add('name')
            ->add('crm_id',null, array(
                'required' => false,
            ))
            ->add('defaultPrice', null, array(
                  'required' => false,
            ))
            ->add('placements',  new PlacementTypeReferenceType($this->em)
            )
            ->add('site',null, array(
                'required' => true,
            ))
            ->add('payment_type','choice',array(
                  'attr' => array(
                    'class' => 'payment_type'
                  ),
                  'choices' => array(
                    'impression' => 'impression',
                    'monthly'    => 'monthly',
                    'daily'      => 'daily',
                    'percentage' => 'percentage',
                    'rotation'   => 'rotation',
                 ),
                  'data' => 'impression'
            ))
            ->add('default_rotations', 'choice',array(
                  'required' => false,
                  'choices'  => array(
                        1  => 1,
                        2  => 2,
                        3  => 3,
                        4  => 4,
                        5  => 5,
                    ),
                  'data' => 0,
                  'placeholder' => 'Choose rotations',
                  'mapped'  => false
            ))
            ->add('isActive',null, array(
                  'label' => 'Active',
                  'required' => false,
                  'attr' => array(
                    'class' => 'js-switch',
                    'data-switchery' => true,
                    'style' => 'display:none'
            )))

;

    }

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

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

这里是 PlacementTypeReferenceType

<?php

namespace AppBundle\Form\Type;


use Symfony\Component\Form\AbstractType;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\FormBuilderInterface;
use Doctrine\ORM\Query;


class PlacementTypeReferenceType extends AbstractType
{
    private $em;

    public function __construct($em)
    {
        $this->em = $em;
    }

    /**
     * @param FormBuilderInterface $builder
     * @param array $options
     */
    public function buildForm(FormBuilderInterface $builder, array $options)
    {
        /* Find all placement types and build form from them */
        $placementTypes = $this->em->getRepository('AppBundle:PlacementType')->findAll(Query::HYDRATE_ARRAY);
         // THIS DOESN'T WORK ALSO !!!
        /*if(!empty($placementTypes))
        {

            foreach($placementTypes as $item) {

                $builder
                    ->add('placementType','checkbox',array(
                                            'value' => $item->getId(),
                                            'label' => $item->getName(),
                ))
                    ->add('coefficient');
            }
        }*/
    }

    public function configureOptions(OptionsResolver $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'AppBundle\Entity\PlacementTypeReference',
            )
        );
    }



    public function getName()
    {
        return 'appbundle_ptreference';
    }
}

我还尝试制作集合数据原型,并将placementTypes从控制器发送到twig,用javascript循环它并为每一行制作原型实例但我希望有一种更清洁的方式。 任何人都可以建议如何解决这个或在哪里看?

1 个答案:

答案 0 :(得分:0)

我认为你需要表格活动。具体来说,请检查this tutorial