Symfony 2. Controller的createForm不会将Model绑定到子模型

时间:2014-12-16 08:15:03

标签: php symfony

我有2个型号,2个来自型号。 FormType“EventSchedule”是“Event”的子表单。当我尝试在我的控制器中使用$this->createForm(new EventType(), $event);时,我得到了表单,但EventSchedules(它是Event的一部分)没有相关事件的链接。

/**
 * Event
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Voulidance\SharedBundle\Repository\EventRepository")
 */
class Event extends BaseEntity {

    /**
     * @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)
     * @Assert\Length(max = "50", maxMessage="The value is too long. It should have maximum {{ limit }} characters")
     * @Assert\NotBlank() 
     */
    private $name;

    /**
     *
     * @var \DateTime
     * 
     * @ORM\Column(name="start_date", type="datetime")
     * @Assert\DateTime(message = "The date should be in format 'mm/dd/yyyy'.")
     * @Assert\NotBlank(message = "Start date field should not be blank.")
     */
    private $startDate;

    /**
     *
     * @var \DateTime
     * 
     * @ORM\Column(name="end_date", type="datetime")
     * @Assert\DateTime(message = "The date should be in format 'mm/dd/yyyy'.")
     * @Assert\NotBlank(message = "End date field should not be blank.")
     */
    private $endDate;

    /**
     * @ORM\OneToMany(targetEntity="EventSchedule", mappedBy="event", cascade={"persist"})
     * @ORM\OrderBy({"dayOfWeek" = "ASC", "startTime" = "ASC"})
     */
    protected $eventSchedules;

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

    public function getId() {
        return $this->id;
    }

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

    public function getStartDate() {
        return $this->startDate;
    }

    public function getEndDate() {
        return $this->endDate;
    }

    public function getEventSchedules() {
        return $this->eventSchedules;
    }

    public function setId($id) {
        $this->id = $id;
    }

    public function setName($name) {
        $this->name = $name;
    }

    public function setStartDate($startDate) {
        $this->startDate = $startDate;
    }

    public function setEndDate($endDate) {
        $this->endDate = $endDate;
    }

    public function setEventSchedules($eventSchedules) {
        $this->eventSchedules = $eventSchedules;
    }

    public function addEventSchedule(EventSchedule $eventSchedule)
    {
        $this->eventSchedules->add($eventSchedule);
    }

     public function removeEventSchedule(EventSchedule $eventSchedule)
    {
        $this->eventSchedules->removeElement($eventSchedule);
    }




   /**
 * EventSchedule
 *
 * @ORM\Table()
 * @ORM\Entity(repositoryClass="Voulidance\SharedBundle\Repository\EventScheduleRepository")
 */
class EventSchedule extends BaseEntity{

    /**
     * @var integer
     *
     * @ORM\Column(name="id", type="integer")
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="AUTO")
     */
    private $id;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="startTime", type="time", nullable=true)
     * @Assert\Time()
     * @Assert\NotBlank(message="Please, fill in all fields.")
     */
    private $startTime;

    /**
     * @var \DateTime
     *
     * @ORM\Column(name="endTime", type="time", nullable=true)
     * @Assert\Time()
     * @Assert\NotBlank(message="Please, fill in all fields.")
     */
    private $endTime;

    /**
     * @var integer
     *
     * @ORM\Column(name="dayOfWeek", type="integer")
     * @Assert\NotBlank(message="Please, fill in all fields.")
     */
    private $dayOfWeek;

    /**
     * @ORM\ManyToOne(targetEntity="Event", inversedBy="eventSchedules")
     * @ORM\JoinColumn(name="event_id", referencedColumnName="id")
     * @Assert\Valid
     * @Assert\NotBlank(message="Please, fill in all fields.")
     */
    protected $event;


    //Assert\NotBlank(message="Please, fill in all fields.")

    public function getId() {
        return $this->id;
    }

    public function getStartTime() {
        return $this->startTime;
    }

    public function getEndTime() {
        return $this->endTime;
    }

    public function getDayOfWeek() {
        return $this->dayOfWeek;
    }

    public function getEvent() {
        return $this->event;
    }

    public function setId($id) {
        $this->id = $id;
        return $this;
    }

    public function setStartTime($startTime) {
        $this->startTime = $startTime;
        return $this;
    }

    public function setEndTime($endTime) {
        $this->endTime = $endTime;
        return $this;
    }

    public function setDayOfWeek($dayOfWeek) {
        $this->dayOfWeek = $dayOfWeek;
        return $this;
    }

    public function setEvent($event) {
        $this->event = $event;
        return $this;
    }

}

    class EventType extends AbstractType{

    public function buildForm(FormBuilderInterface $builder, array $options){
        $builder->add('name', null, array(
            'label' => false,
            'attr' => array('id'=>"page-name", 'size'=>"24", 'class'=>'auth'),
            'required'=>true
        ))->add('startDate', 'date', array(
            'widget' => 'single_text',
            'label' => false,
            'format' => 'MM/dd/yyyy',
            'invalid_message' => "Start date format should be 'mm/dd/yyyy'.",
            'attr' => array('data-date'=>"", 'placeholder'=>"mm/dd/yyyy", 'size'=>"18",'class'=>"auth date holiday-start-date hasDatepicker", 'id'=>"holiday-start-date")
        ))->add('endDate', 'date', array(
            'widget' => 'single_text',
            'label' => false,
            'format' => 'MM/dd/yyyy',
            'invalid_message' => "End date format should be 'mm/dd/yyyy'.",
            'attr' => array('data-date'=>"", 'placeholder'=>"mm/dd/yyyy", 'size'=>"18",'class'=>"auth date holiday-start-date hasDatepicker", 'id'=>"holiday-start-date")
        ))->add('eventSchedules', 'collection', array(
                'type' => new EventScheduleType(),
                'cascade_validation' => true,
                'allow_add'    => true,
                'allow_delete' => true,
                'by_reference' => false,
                'label' => false,
                'error_bubbling'=>false
            ))->add('id', 'hidden');
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver)
    {
        $resolver->setDefaults(array(
            'data_class' => 'Voulidance\SharedBundle\Entity\Event',
            'cascade_validation' => false,
            'validation_groups' => false
        ));
    }

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

    class EventScheduleType extends AbstractType {

    public function buildForm(FormBuilderInterface $builder, array $options) {
        $builder->add('startTime', 'us_time', array(
            'widget' => 'text',
            'label' => 'From',
            'attr' => array('maxlength' => '2', 'placeholder' => 'hh:mm'),
            'invalid_message' => 'Time value is not valid.',
            'error_bubbling' => false
        ))->add('endTime', 'us_time', array(
            'widget' => 'text',
            'label' => 'To',
            'attr' => array('maxlength' => '2', 'placeholder' => 'hh:mm'),
            'invalid_message' => 'Time value is not valid.',
            'error_bubbling' => false
        ))->add('dayOfWeek', 'choice', array(
            'choices' => array(
                1 => 'Everyday',
                2 => 'Sunday',
                3 => 'Monday',
                4 => 'Tuesday',
                5 => 'Wednesday',
                6 => 'Thursday',
                7 => 'Friday',
                8 => 'Saturday',
            ),
            'label' => false,
            'attr' => array('size'=>'15'),
            'multiple' => false,
            'error_bubbling' => false
        ))->add('id', 'hidden', array('label' => false));
    }

    public function setDefaultOptions(OptionsResolverInterface $resolver) {
        $resolver->setDefaults(array(
            'data_class' => 'Voulidance\SharedBundle\Entity\EventSchedule',
            'cascade_validation' => false,
            'validation_groups' => false
        ));
    }

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

}

     /**
     * Save event
     *
     * @Route("/save", name="admin_event_save")
     * @Template("VoulidanceAdminBundle:Event:index.html.twig")
     */
    public function saveAction(Request $request) {

        $em = $this->getDoctrine()->getManager();
        $eventRepository = $em->getRepository("VoulidanceSharedBundle:Event");
        $event = new Event();
        $form = $this->createForm(new EventType(), $event);
        $form->handleRequest($request);
        $schedules = $form->get('eventSchedules')->getData();
        foreach($schedules as $schedule){
            $schedule->setEvent($event);
        }
        if ($form->isValid()) {
            $errors = $this->validateSchedules($schedules);
            if(count($errors) > 0){
                return new JsonResponse(array('subformError'=>true, 'errors'=>$errors));
            }
            $em->persist($event);
            $em->flush();
            return new JsonResponse(array('success' => true, 'events'=>$eventRepository->findAll()));
        }
        return new JsonResponse(array('error' => true, 'errors'=>(string)$form->getErrors(true)));
    }

2 个答案:

答案 0 :(得分:0)

虽然我现在无法测试代码,但我认为我可以看到问题并回答您的问题,以便您可以使用它。

$schedules = $form->get('eventSchedules')->getData();

应该是:

$schedules = $event-> getEventSchedules();

因为你需要$ form-> handleRequest($ request)的映射数据;正在填充$ event对象。

答案 1 :(得分:0)

解决方案是在事件类的addEventSchedule方法中将event设置为eventSchedule。

public function addEventSchedule(EventSchedule $eventSchedule)
{
    $eventSchedule->addEvent($this);
    $this->eventSchedules->add($eventSchedule);
}