我有一个来自CalendarMeeting
的继承实体CalendarEvent
,它添加了两个相关的实体。其中一个是Address
实体。提交CalendarMeeting
后,我想检查Address
表单是否为空,如果是,请删除表单,以便不将Address
保存到数据库中。我的代码如下:
CalendarMeeting
:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
use Doctrine\Common\Collections\ArrayCollection;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\CalendarMeetingRepository")
* @ORM\Table(name="calendar_meetings")
*/
class CalendarMeeting extends CalendarEvent
{
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Address", cascade={"persist"})
* @ORM\JoinColumn(name="address_id", referencedColumnName="id")
*/
private $address;
/**
* @var ArrayCollection
*
* @ORM\ManyToMany(targetEntity="AppBundle\Entity\User")
* @ORM\JoinTable(
* name="User2CalendarMeeting",
* joinColumns={@ORM\JoinColumn(name="calendar_meeting_id", referencedColumnName="id", nullable=false)},
* inverseJoinColumns={@ORM\JoinColumn(name="user_id", referencedColumnName="id", nullable=false)}
* )
*/
private $users;
/**
* @return mixed
*/
public function getAddress()
{
return $this->address;
}
/**
* @param mixed $address
* @return CalendarMeeting
*/
public function setAddress($address)
{
$this->address = $address;
return $this;
}
/**
* @return ArrayCollection
*/
public function getUsers()
{
return $this->users;
}
/**
* @param User $user
* @return void
*/
public function addUser(User $user)
{
$this->users->add($user);
}
/**
* @param User $user
* @return void
*/
public function removeUser(User $user)
{
$this->users->removeElement($user);
}
}
Address
实体:
<?php
namespace AppBundle\Entity;
use Doctrine\ORM\Mapping AS ORM;
/**
* @ORM\Entity(repositoryClass="AppBundle\Entity\AddressRepository")
* @ORM\Table(name="addresses")
* @ORM\HasLifecycleCallbacks
*/
class Address
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $name;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $address_1;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $address_2;
/**
* @ORM\Column(type="integer", nullable=true)
*/
private $postal_code;
/**
* @ORM\Column(type="string", nullable=true)
*/
private $postal_address;
/**
* @ORM\Column(type="decimal", nullable=true, precision=10, scale=6)
*/
private $latitude;
/**
* @ORM\Column(type="decimal", nullable=true, precision=11, scale=6)
*/
private $longitude;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $created;
/**
* @ORM\Column(type="datetime", nullable=true)
*/
private $updated;
/**
* @return mixed
*/
public function getId() {
return $this->id;
}
/**
* @return mixed
*/
public function getName() {
return $this->name;
}
/**
* @param mixed $name
* @return Address
*/
public function setName($name) {
$this->name = $name;
return $this;
}
/**
* @return mixed
*/
public function getAddress1() {
return $this->address_1;
}
/**
* @param mixed $address_1
* @return Address
*/
public function setAddress1($address_1) {
$this->address_1 = $address_1;
return $this;
}
/**
* @return mixed
*/
public function getAddress2() {
return $this->address_2;
}
/**
* @param mixed $address_2
* @return Address
*/
public function setAddress2($address_2) {
$this->address_2 = $address_2;
return $this;
}
/**
* @return mixed
*/
public function getPostalCode() {
return $this->postal_code;
}
/**
* @param mixed $postal_code
* @return Address
*/
public function setPostalCode($postal_code) {
$this->postal_code = $postal_code;
return $this;
}
/**
* @return mixed
*/
public function getPostalAddress() {
return $this->postal_address;
}
/**
* @param mixed $postal_address
* @return Address
*/
public function setPostalAddress($postal_address) {
$this->postal_address = $postal_address;
return $this;
}
/**
* @return mixed
*/
public function getLatitude() {
return $this->latitude;
}
/**
* @param mixed $latitude
* @return Address
*/
public function setLatitude($latitude) {
$this->latitude = $latitude;
return $this;
}
/**
* @return mixed
*/
public function getLongitude() {
return $this->longitude;
}
/**
* @param mixed $longitude
* @return Address
*/
public function setLongitude($longitude) {
$this->longitude = $longitude;
return $this;
}
/**
* @return mixed
*/
public function getCreated()
{
return $this->created;
}
/**
* @param \DateTime $created
* @return Address
*/
public function setCreated(\DateTime $created)
{
$this->created = $created;
return $this;
}
/**
* @return mixed
*/
public function getUpdated()
{
return $this->updated;
}
/**
* @param mixed $updated
* @return ShiftChange
*/
public function setUpdated(\DateTime $updated)
{
$this->updated = $updated;
return $this;
}
/**
* @ORM\PrePersist
* @ORM\PreUpdate
*/
public function updateTimestamps()
{
$this->setUpdated(new \DateTime('now'));
if ($this->getCreated() === null) {
$this->setCreated(new \DateTime('now'));
}
}
}
没有CalendarMeetingType
只有继承的CalendarEventType
,我在其中使用事件侦听器检查编辑的实体类型。它看起来像这样:
<?php
namespace AppBundle\Form;
use AppBundle\Entity\CalendarMeeting;
use Symfony\Component\Form\AbstractType;
use Symfony\Component\Form\FormBuilderInterface;
use Symfony\Component\OptionsResolver\OptionsResolverInterface;
use Symfony\Component\Form\FormEvents;
use Symfony\Component\Form\FormEvent;
class CalendarEventType extends AbstractType
{
protected $start = false;
protected $end = false;
public function __construct($date = null)
{
if ($date) {
$this->start = new \DateTime($date . ' 09:00:00');
$this->end = new \DateTime($date . ' 10:00:00');
}
}
/**
* @param FormBuilderInterface $builder
* @param array $options
*/
public function buildForm(FormBuilderInterface $builder, array $options)
{
$builder
->add('name', null, array(
'attr' => array(
'placeholder' => 'app.forms.calendar.name',
),
'label' => 'app.forms.calendar.name',
'translation_domain' => 'AppBundle'
))
->add('description', null, array(
'label' => 'app.forms.calendar.description',
'translation_domain' => 'AppBundle'
))
->add('event_type', 'choice', array(
'label' => "app.forms.calendar.event_type.label",
'choices' => array(
'event' => 'app.forms.calendar.event_type.event',
'meeting' => 'app.forms.calendar.event_type.meeting',
'holiday' => 'app.forms.calendar.event_type.holiday',
),
'required' => true,
'expanded' => false,
'multiple' => false,
'mapped' => false,
'translation_domain' => 'AppBundle'
));
if ($this->start && $this->end) {
$builder
->add('start', 'datetime', array(
'date_widget' => 'single_text',
'time_widget' => 'text',
'data' => $this->start,
'label' => 'app.forms.calendar.start',
'translation_domain' => 'AppBundle',
))
->add('end', 'datetime', array(
'date_widget' => 'single_text',
'time_widget' => 'text',
'data' => $this->end,
'label' => 'app.forms.calendar.end',
'translation_domain' => 'AppBundle'
));
} else {
$builder
->add('start', 'datetime', array(
'date_widget' => 'single_text',
'time_widget' => 'text',
'label' => 'app.forms.calendar.start',
'translation_domain' => 'AppBundle',
))
->add('end', 'datetime', array(
'date_widget' => 'single_text',
'time_widget' => 'text',
'label' => 'app.forms.calendar.end',
'translation_domain' => 'AppBundle'
));
}
$builder->addEventListener(
FormEvents::PRE_SET_DATA,
array($this, 'onPreSetData')
);
$builder->addEventListener(
FormEvents::PRE_SUBMIT,
array($this, 'onPreSubmit')
);
}
/**
* @param \Symfony\Component\Form\FormEvent $event
*/
public function onPreSetData(FormEvent $event)
{
$form = $event->getForm();
$data = $event->getData();
/* Check we're looking at the right data/form */
if ($data instanceof CalendarMeeting) {
$form->add('address', new AddressType());
}
}
/**
* @param \Symfony\Component\Form\FormEvent $event
*/
public function onPreSubmit(FormEvent $event)
{
$data = $event->getData();
$form = $event->getForm();
if ($data instanceof CalendarMeeting) {
if ($data->getAddress()->getAddress1() == "") {
$form->remove('address');
}
}
}
/**
* @param OptionsResolverInterface $resolver
*/
public function setDefaultOptions(OptionsResolverInterface $resolver)
{
$resolver->setDefaults(array(
'data_class' => 'AppBundle\Entity\CalendarEvent'
));
}
/**
* @return string
*/
public function getName()
{
return 'appbundle_calendarevent';
}
}
onPreSubmit
功能显然不起作用,但唉,这是我希望这是正确的方法。我无法弄清楚如何解决这个问题(另一种方式)。
现在发生的事情是,当我在地址表单字段中提交没有任何数据的表单时,地址仅使用空值保存到数据库。如何在保存地址时停止该地址?
非常感谢你的时间。
此致 托米
答案 0 :(得分:0)
我想出来了。我完全错了。解决方案是在onDelete="CASCADE"
CalendarMeeting
上添加address
:
(编辑:onDelete="CASCADE"
已从联接列中删除,因为它不需要)
/**
* @ORM\ManyToOne(targetEntity="AppBundle\Entity\Address", cascade={"persist"})
* @ORM\JoinColumn(name="address_id", referencedColumnName="id", nullable=true)
*/
private $address;
在setAddress
函数上,最初将address参数设置为null:
/**
* @param Address $address
* @return CalendarMeeting
*/
public function setAddress(Address $address = null)
{
$this->address = $address;
return $this;
}
然后在CalendarEventType
我更改了address
类型添加到以下内容,因此它接受null:
if ($data instanceof CalendarMeeting) {
$form->add('address', new AddressType(), array(
'required' => false,
));
}
最后在CalendarEventController中,我检查地址字段是否包含任何值。如果不是,请将地址设置为null:
// Check if calendar meeting
if($entity instanceof CalendarMeeting) {
$address_form = $editForm->get('address')->getData();
if($address_form === null ||
($address_form->getName() === null &&
$address_form->getAddress1() === null &&
$address_form->getPostalCode() === null &&
$address_form->getPostalAddress() == null)
) {
$entity->setAddress(null);
}
}
$em->flush();
return ...redirect...
如果有人有更好的解决方案,请发一个答案,我会接受。此外,如果这是一个肮脏的解决方案,请评论。我有一种感觉.. :)