Я отправляю форму в Symfony с набором подформ. Доктрина, кажется, спасает только последнюю сущность в этой коллекции. Как мне заставить его сохранить все сущности в коллекции?
Я дважды проверил свой код и следовал нескольким учебникам, чтобы убедиться, что он правильный.
EnrichmentApplication
/**
* @ORM\Entity
*/
class EnrichmentApplication
{
//...
/**
* @var array
*
* @ORM\OneToMany(targetEntity="EnrichmentActivity", mappedBy="application", cascade={"persist"})
*/
private $activities;
/**
* @var array
*
* @ORM\OneToMany(targetEntity="EnrichmentActivityCosts", mappedBy="application", cascade={"persist"})
*/
private $activityCosts;
**
* @var string
*
* @ORM\Column(name="project_outline", type="text")
*/
private $projectOutline;
//...
public function __construct()
{
$this->activities = new ArrayCollection();
$this->activityCosts = new ArrayCollection();
}
/**
* Set activityTypes
*
* @param array $activityTypes
*
* @return EnrichmentApplication
*/
public function setActivityTypes($activityTypes)
{
$this->activityTypes = $activityTypes;
return $this;
}
/**
* Get activityTypes
*
* @return array
*/
public function getActivityTypes()
{
return $this->activityTypes;
}
/**
* Set activities
*
* @param array $activities
*
* @return EnrichmentApplication
*/
public function setActivities($activities)
{
$this->activities = $activities;
return $this;
}
/**
* Get activities
*
* @return array
*/
public function getActivities()
{
return $this->activities;
}
/**
* Add activity
*
* @param array $activity
*
* @return EnrichmentApplication
*/
public function addActivities(EnrichmentActivity $activity)
{
$activity->setApplication($this);
if (!$this->activities->contains($activity))
{
$this->activities->add($activity);
}
return $this;
}
/**
* Set activityCosts
*
* @param array $activityCosts
*
* @return EnrichmentApplication
*/
public function setActivityCosts($activityCosts)
{
$this->activityCosts = $activityCosts;
return $this;
}
/**
* Get activityCosts
*
* @return array
*/
public function getActivityCosts()
{
return $this->activityCosts;
}
/**
* Add activityCost
*
* @param EnrichmentActivityCosts $activityCost
*
* @return EnrichmentApplication
*/
public function addActivityCosts(EnrichmentActivityCosts $activityCost)
{
$activityCost->setApplication($this);
if (!$this->activityCosts->contains($activityCost))
{
$this->activityCosts->add($activityCost);
}
return $this;
}
/**
* Set projectOutline
*
* @param string $projectOutline
*
* @return EnrichmentApplication
*/
public function setProjectOutline($projectOutline)
{
$this->projectOutline = $projectOutline;
return $this;
}
/**
* Get projectOutline
*
* @return string
*/
public function getProjectOutline()
{
return $this->projectOutline;
}
//...
}
EnrichmentActivity
/**
* @var int
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var array
*
* @ORM\ManyToOne(targetEntity="EnrichmentApplication", inversedBy="activities")
* @ORM\JoinColumn(name="application_id", referencedColumnName="id")
*/
private $application;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="date")
*/
private $date;
/**
* @var \DateTime
*
* @ORM\Column(name="start_time", type="time")
*/
private $startTime;
/**
* @var \DateTime
*
* @ORM\Column(name="end_time", type="time")
*/
private $endTime;
/**
* @var int
*
* @ORM\Column(name="total_students", type="integer")
*/
private $totalStudents;
/**
* @var \DateTime
*
* @ORM\Column(name="date", type="date")
*/
/**
* Get id
*
* @return int
*/
public function getId()
{
return $this->id;
}
public function __clone()
{
$this->id = null;
$this->application = null;
}
/**
* Set application
*
* @param EnrichmentApplication $application
*
* @return EnrichmentActivity
*/
public function setApplication($application)
{
$this->application = $application;
return $this;
}
/**
* Get application
*
* @return EnrichmentApplication
*/
public function getApplication()
{
return $this->application;
}
/**
* Set date
*
* @param \DateTime $date
*
* @return EnrichmentActivity
*/
public function setDate($date)
{
$this->date = $date;
return $this;
}
/**
* Get date
*
* @return \DateTime
*/
public function getDate()
{
return $this->date;
}
/**
* Set startTime
*
* @param \DateTime $startTime
*
* @return EnrichmentActivity
*/
public function setStartTime($startTime)
{
$this->startTime = $startTime;
return $this;
}
/**
* Get startTime
*
* @return \DateTime
*/
public function getStartTime()
{
return $this->startTime;
}
/**
* Set endTime
*
* @param \DateTime $endTime
*
* @return EnrichmentActivity
*/
public function setEndTime($endTime)
{
$this->endTime = $endTime;
return $this;
}
/**
* Get endTime
*
* @return \DateTime
*/
public function getEndTime()
{
return $this->endTime;
}
/**
* Set totalStudents
*
* @param integer $totalStudents
*
* @return EnrichmentActivity
*/
public function setTotalStudents($totalStudents)
{
$this->totalStudents = $totalStudents;
return $this;
}
/**
* Get totalStudents
*
* @return int
*/
public function getTotalStudents()
{
return $this->totalStudents;
}
}
EnrichmentApplicationType (форма)
namespace AppBundle\Form;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolver;
use Symfony\Component\Form\Extension\Core\Type as Types;
use Lifo\TypeaheadBundle\Form\Type\TypeaheadType;
class EnrichmentApplicationType extends AbstractType
{
/**
* {@inheritdoc}
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$uniform_col_label = 'col-xs-12 col-sm-5 col-md-4 col-lg-3';
$uniform_col_element = 'col-xs-12 col-sm-7 col-md-8 col-lg-8';
$uniform_col_label_smaller = 'col-xs-12 col-sm-5 col-md-4 col-lg-2';
$uniform_col_element_smaller = 'col-xs-6 col-sm-2 col-md-2 col-lg-2';
$uniform_col_element_offset = ' col-sm-offset-5 col-md-offset-4 col-lg-offset-3';
$uniform_col_fullwidth = 'col-xs-12 col-sm-12';
$builder->add('manager', TypeaheadType::class, array(
'label' => 'Head of Department',
'route' => 'ajax_name_search',
'minLength' => 3,
'render' => 'fullName',
'attr' => array(
'data-second-glyph' => 'user',
'data-label-col' => 'col-xs-12 col-sm-5 col-md-4 col-lg-4 ',
'data-group-col' => 'col-xs-12 col-sm-7 col-md-8 col-lg-6'
)
))
->add('personResponsible', TypeaheadType::class, array(
'label' => 'Person responsible for activity delivery',
'route' => 'ajax_name_search',
'minLength' => 3,
'render' => 'fullName',
'attr' => array(
'data-second-glyph' => 'user',
'data-label-col' => 'col-xs-12 col-sm-5 col-md-5 col-lg-4',
'data-group-col' => 'col-xs-12 col-sm-7 col-md-7 col-lg-6'
)
))
//->add('author') //populated by LDAP
->add('activityTitle', Types\TextType::class, array(
'label' => 'Title of proposed activity',
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('activityTypes', Types\ChoiceType::class, array(
'label' => 'Activity type',
'choices' => $options['activityTypes'],
'expanded' => true,
'help' => 'Please select all that apply.',
'multiple' => true,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('activities', Types\CollectionType::class, array(
'entry_type' => EnrichmentActivityType::class,
'allow_add' => true,
'by_reference' => false,
'entry_options' => array(
'empty_data' => new \AppBundle\Entity\EnrichmentActivity(),
),
'attr' => array(
'data-label-col' => 'col-sm-12',
'data-group-col' => 'col-sm-12'
)
))
->add('activityCosts', Types\CollectionType::class, array(
'entry_type' => EnrichmentActivityCostsType::class,
'allow_add' => true,
'entry_options' => array(
'empty_data' => new \AppBundle\Entity\EnrichmentActivityCosts(),
),
'attr' => array(
'data-label-col' => 'col-xs-12 col-sm-3 col-md-4 col-lg-3',
'data-group-col' => 'col-xs-12 col-sm-9 col-md-8 col-lg-9'
)
))
->add('projectOutline', Types\TextareaType::class, array(
'label' => 'Activity outline and rationale',
'help' => 'Provide background information of your activity, what you intend to do and how it will impact on students\' life skills development.',
#
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('projectObjectives', Types\CollectionType::class, array(
'entry_type' => Types\TextType::class,
'label' => 'Activity objectives & outputs',
'help' => 'Please describe what you intend to achieve. Will there be any specific outputs (eg. deliver a workshop/fundraiser)?',
'allow_add' => true,
'prototype' => true,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('studentConsulted', Types\TextareaType::class, array(
'label' => 'How have the students been consulted/involved with the design of this activity?',
'help' => 'For example, have students requested this activity? Have they been involved in the planning?',
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_fullwidth
)
))
->add('studentInvolvement', Types\TextareaType::class, array(
'label' => 'Will the students be involved in the delivery of the activity?',
'help' => 'Will students be participating only or will they also be volunteering to run this activity?',
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_fullwidth
)
))
->add('communityContribution', Types\ChoiceType::class, array(
'choices' => $options['communityContrib'],
'expanded' => true,
'multiple' => true,
'required' => false,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('studySuccess', Types\ChoiceType::class, array(
'label' => 'Study and Work Success',
'choices' => $options['studySuccess'],
'expanded' => true,
'multiple' => true,
'required' => false,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('lifestyles', Types\ChoiceType::class, array(
'label' => 'Healthy & Happy Lifestyles',
'choices' => $options['lifestyles'],
'expanded' => true,
'multiple' => true,
'required' => false,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('totalStudents', Types\IntegerType::class, array(
'label' => 'Total number of students:',
'scale' => 0,
'attr' => array(
'data-label-col' => $uniform_col_label_smaller,
'data-group-col' => $uniform_col_element_smaller
)
))
->add('studentsUnder16', Types\IntegerType::class, array(
'label' => 'Aged under 16 years:',
'scale' => 0,
'attr' => array(
'data-label-col' => $uniform_col_label_smaller,
'data-group-col' => $uniform_col_element_smaller
)
))
->add('students16To18', Types\IntegerType::class, array(
'label' => 'Aged 16 to 18 years:',
'scale' => 0,
'attr' => array(
'data-label-col' => $uniform_col_label_smaller,
'data-group-col' => $uniform_col_element_smaller
)
))
->add('studentsOver18', Types\IntegerType::class, array(
'label' => 'Aged over 18 years:',
'scale' => 0,
'attr' => array(
'data-label-col' => $uniform_col_label_smaller,
'data-group-col' => $uniform_col_element_smaller
)
))
->add('alsStudents', Types\IntegerType::class, array(
'label' => 'Students accessing Additional Learning Support',
'scale' => 0,
'attr' => array(
'data-label-col' => 'col-xs-12 col-sm-6 col-md-5 col-lg-4',
'data-group-col' => $uniform_col_element_smaller
)
))
->add('availableAccrossCollege', Types\ChoiceType::class, array(
'label' => 'Is the activity only open to students from across college?',
'choices' => array(
'Yes' => true,
'No' => false
),
'expanded' => true,
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_element_offset
)
))
->add('availableOutside', Types\ChoiceType::class, array(
'label' => 'Is the activity open to students from outside college?',
'choices' => array(
'Yes' => true,
'No' => false
),
'expanded' => true,
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_element_offset
)
))
->add('availableOnlyDepartment', Types\ChoiceType::class, array(
'label' => 'Is the activity only open to students from a specific department?',
'choices' => array(
'Yes' => true,
'No' => false
),
'expanded' => true,
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_element_offset
)
))
->add('availableDepartment', Types\TextType::class, array(
'label' => 'If yes, please specify:',
'required' => false,
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
)
))
->add('availableOnlyCurriculumArea', Types\ChoiceType::class, array(
'label' => 'Is the activity only open to students from a specific curriculum area?',
'choices' => array(
'Yes' => true,
'No' => false
),
'expanded' => true,
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_element_offset
)
))
->add('availableCurriculumArea', Types\TextType::class, array(
'label' => 'If yes, please specify:',
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
),
'required' => false,
))
->add('availableOnlyCourse', Types\ChoiceType::class, array(
'label' => 'Is the activity open to students from a specific course?',
'choices' => array(
'Yes' => true,
'No' => false
),
'expanded' => true,
'attr' => array(
'data-label-col' => $uniform_col_fullwidth,
'data-group-col' => $uniform_col_element_offset
)
))
->add('availableCourse', Types\TextType::class, array(
'label' => 'If yes, please specify:',
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
),
'required' => false,
))
->add('availableOutsideDetail', Types\TextType::class, array(
'label' => 'If yes, please specify:',
'attr' => array(
'data-label-col' => $uniform_col_label,
'data-group-col' => $uniform_col_element
),
'required' => false,
))
->add('behaviouralEngagement', Types\CheckboxType::class, array(
'required' => false,
))
->add('emotionalEngagement', Types\CheckboxType::class, array(
'required' => false,
))
->add('cognitiveEngagement', Types\CheckboxType::class, array(
'required' => false,
))
->add('noStudentsBronze', Types\IntegerType::class, array(
'label' => 'Bronze',
'scale' => 0,
'attr' => array(
'data-label-col' => 'col-xs-5 col-sm-2 col-md-2 col-lg-1',
'data-group-col' => 'col-xs-6 col-sm-2 col-md-2 col-lg-2'
)
))
->add('noStudentsSilver', Types\IntegerType::class, array(
'label' => 'Silver',
'scale' => 0,
'attr' => array(
'data-label-col' => 'col-xs-5 col-sm-2 col-md-2 col-lg-1',
'data-group-col' => 'col-xs-6 col-sm-2 col-md-2 col-lg-2'
)
))
->add('noStudentsGold', Types\IntegerType::class, array(
'label' => 'Gold',
'scale' => 0,
'attr' => array(
'data-label-col' => 'col-xs-5 col-sm-2 col-md-2 col-lg-1',
'data-group-col' => 'col-xs-6 col-sm-2 col-md-2 col-lg-2'
)
))
;
}
/**
* {@inheritdoc}
*/
public function configureOptions(OptionsResolver $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\EnrichmentApplication',
'activityTypes' => null,
'communityContrib' => null,
'studySuccess' => null,
'lifestyles' => null,
));
}
/**
* {@inheritdoc}
*/
public function getBlockPrefix()
{
return 'appbundle_enrichmentapplication';
}
}
Окружающая среда
- CentOS 7
- PHP 7.1
- MariaDB 10