Symfony 4 + 奏鸣曲管理包 + 关系。表单正在删除子项,但不仅是 parentId
Posted
技术标签:
【中文标题】Symfony 4 + 奏鸣曲管理包 + 关系。表单正在删除子项,但不仅是 parentId【英文标题】:Symfony 4 + sonata admin bundle + relations. Form is deleting children but not only parentId 【发布时间】:2021-07-30 11:27:19 【问题描述】:大家好!我遇到了一些问题。我有奏鸣曲管理员 + symfony 4 + 一些具有多面关系的实体。我有 3 个名为banner videobanner photobanner 的简单表格,现在我想创建管理部分,它将由 1 2 或 3 个简单的横幅视频横幅或 photobbanner 创建。它几乎完成了,但表格有一些错误。我可以创建简单的横幅,并且可以成功创建记录,但是 parentId 是空的,因为它现在没有任何父母,但是后来当我在管理员中设置时 parentId 正在子表中创建,但后来当我尝试删除关系奏鸣曲管理员用子记录删除它,但我希望奏鸣曲管理员只删除 parentId 子记录必须保留 parentId = NULL。
<?php
namespace App\Admin\Action\Banner;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Sonata\AdminBundle\Form\Type\ModelType;
use Sonata\AdminBundle\Admin\AbstractAdmin;
use Sonata\AdminBundle\Form\FormMapper;
use Sonata\AdminBundle\Datagrid\DatagridMapper;
use Sonata\AdminBundle\Datagrid\ListMapper;
use App\Cms\Entity\Banner\NestedBanner;
use App\Admin\Form\DataTransformer\BannerDataTransformer;
use App\Cms\Entity\Banner\Banner;
/**
*
* Class NestedBannerAdmin.
*/
class NestedBannerAdmin extends AbstractAdmin
/**
*
* @param FormMapper $formMapper
*/
protected function configureFormFields(FormMapper $formMapper)
$formMapper->add('title', TextType::class);
$formMapper->add('description', TextareaType::class);
$formMapper->add('banners');
$formMapper->add('photoBanners');
$formMapper->add('videoBanners');
$formMapper->add('promoBlockBanners');
// $formMapper
// ->get('banners')
// ->addModelTransformer(new BannerDataTransformer($this->getSubject()));
/**
*
* @param DatagridMapper $datagridMapper
*/
protected function configureDatagridFilters(DatagridMapper $datagridMapper)
$datagridMapper->add('title');
$datagridMapper->add('description');
$datagridMapper->add('banners');
$datagridMapper->add('photoBanners');
$datagridMapper->add('videoBanners');
$datagridMapper->add('promoBlockBanners');
/**
*
* @param ListMapper $listMapper
*/
protected function configureListFields(ListMapper $listMapper)
$listMapper->addIdentifier('title');
$listMapper->addIdentifier('description');
$listMapper->add(
'banners',
null,
[
'label' => 'Banners',
'sortable' => false,
'allow_add' => false,
'allow_delete' => false,
]
);
$listMapper->add(
'photoBanners',
null,
[
'label' => 'Photo banners',
'sortable' => false,
'allow_add' => true,
'allow_delete' => false,
]
);
$listMapper->add(
'videoBanners',
null,
[
'label' => 'Video banners',
'sortable' => false,
'allow_add' => true,
'allow_delete' => false,
]
);
$listMapper->add(
'promoBlockBanners',
null,
[
'label' => 'Promo block banners',
'sortable' => false,
'allow_add' => true,
'allow_delete' => false,
]
);
public function preUpdate($object)
// dd($object);
if($object instanceof NestedBanner)
foreach ($object->getBanners() as $banner)
$nestedBanner = $banner->getNestedBanner();
if(null == $nestedBanner)
$banner->setNestedBanner($object);
foreach ($object->getVideoBanners() as $banner)
$nestedBanner = $banner->getNestedBanner();
if(null == $nestedBanner)
$banner->setNestedBanner($object);
foreach ($object->getPhotoBanners() as $banner)
$nestedBanner = $banner->getNestedBanner();
if(null == $nestedBanner)
$banner->setNestedBanner($object);
foreach ($object->getPromoBlockBanners() as $banner)
$nestedBanner = $banner->getNestedBanner();
if(null == $nestedBanner)
$banner->setNestedBanner($object);
<?php
namespace App\Cms\Entity\Banner;
use Doctrine\ORM\Mapping as ORM;
use Doctrine\Common\Collections\Collection;
use Doctrine\Common\Collections\ArrayCollection;
use App\Cms\Entity\Banner\Banner;
use App\Cms\Entity\Banner\PhotoBanner;
use App\Cms\Entity\Banner\VideoBanner;
use App\Cms\Entity\Banner\PromoBlockBanner;
/**
*
* @ORM\Entity(repositoryClass="App\Cms\Repository\Banner\NestedBannerRepository")
* @ORM\Table(name="nested_banner")
*/
class NestedBanner
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* @ORM\Column(name="description", type="string", length=255)
*/
private $description;
/**
* @var bannerMaps
*
* @ORM\OneToMany(
* targetEntity="App\Cms\Entity\Banner\Banner",
* mappedBy="nestedBanner",
* orphanRemoval=true,
* cascade="persist"
* )
*
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $banners;
/**
* @var bannerMaps
*
* @ORM\OneToMany(
* targetEntity="App\Cms\Entity\Banner\VideoBanner",
* mappedBy="nestedBanner",
* orphanRemoval=true,
* cascade="persist")
*
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $videoBanners;
/**
* @var bannerMaps
*
* @ORM\OneToMany(
* targetEntity="App\Cms\Entity\Banner\PhotoBanner",
* mappedBy="nestedBanner",
* cascade="persist"),
* orphanRemoval=false
*
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $photoBanners;
/**
* @var bannerMaps
*
* @ORM\OneToMany(
* targetEntity="App\Cms\Entity\Banner\PromoBlockBanner",
* mappedBy="nestedBanner",
* cascade="persist")
*
* @ORM\JoinColumn(onDelete="CASCADE")
*/
private $promoBlockBanners;
/**
*
* @param type $id
* @param type $title
* @param type $description
* @param Collection $bannerMaps
*/
public function __construct()
// $this->banners = new ArrayCollection();
// $this->videoBanners = new ArrayCollection();
// $this->photoBanners = new ArrayCollection();
// $this->promoBlockBanners = new ArrayCollection();
/**
*
* @return int
*/
public function getId(): ?int
return $this->id;
/**
*
* @return string
*/
public function getTitle(): ?string
return $this->title;
/**
*
* @return string
*/
public function getBanners(): ?Collection
return $this->banners;
/**
*
* @return string
*/
public function getVideoBanners(): ?Collection
return $this->videoBanners;
/**
*
* @return string
*/
public function getPhotoBanners(): ?Collection
return $this->photoBanners;
/**
*
* @return string
*/
public function getPromoBlockBanners(): ?Collection
return $this->promoBlockBanners;
/**
*
* @return string
*/
public function getDescription(): ?string
return $this->description;
/**
*
* @param int $id
*/
public function setId(int $id)
$this->id = $id;
/**
*
* @param string $title
*/
public function setTitle(string $title)
$this->title = $title;
/**
*
* @param Collection $banners
*/
public function addBanner(Banner $banner): self
dd('addBanner');
$this->banners[] = $banner;
return $this;
/**
*
* @param Collection $banners
*/
public function addBanners(Collection $banners): self
dd('addBanners');
$this->banners[] = $banner;
return $this;
/**
*
* @param Collection $banners
*/
public function setBanners(Collection $banners): self
dd('setBanners');
foreach($banners as $banner)
$banner->setNestedBanner($this);
$this->banners = $banners;
return $this;
/**
*
* @param Collection $banners
*/
public function removeBanner(Banner $banners): self
dd('removeBanner');
foreach($banners as $banner)
$banner->setNestedBanner($this);
$this->banners = $banners;
return $this;
/**
*
* @param Collection $banners
*/
public function banner(Banner $banners): self
dd('Banner');
foreach($banners as $banner)
$banner->setNestedBanner($this);
$this->banners = $banners;
return $this;
/**
*
* @param Collection $videoBanners
*/
public function setVideoBanners(Collection $videoBanners): self
$this->videoBanners = $videoBanners;
return $this;
/**
*
* @param Collection $photoBanners
*/
public function setPhotoBanners(Collection $photoBanners): self
$this->photoBanners = $photoBanners;
return $this;
/**
*
* @param Collection $banners
*/
public function setPromoBlockBanners(Collection $promoBlockBanners): self
$this->promoBlockBanners = $promoBlockBanners;
return $this;
/**
*
* @param string $description
*/
public function setDescription(string $description)
$this->description = $description;
// public function addBanner(Banner $banner): NestedBanner
//
//
// dd($banner);
// $this->banners->add($banner);
//
// return $this;
//
//
// public function setBanner(Banner $banner): NestedBanner
//
//
// dd($banner);
// $this->banners->add($banner);
//
// return $this;
//
// public function addPhotoBanner(PhotoBanner $photoBanner): NestedBanner
//
// $this->photoBanners->add($photoBanner);
//
// return $this;
//
//
// public function addVideoBanner(VideoBanner $videoBanner): NestedBanner
//
// $this->videoBanners->add($videoBanner);
//
// return $this;
//
//
// public function addPromoBlockBanner(PromoBlockBanner $promoBlockBanner): NestedBanner
//
// $this->promoBlockBanners->add($promoBlockBanner);
//
// return $this;
//
// public function removeBanner(Banner $banner): NestedBanner
//
// $this->banners->removeElement($banner);
//
// return $this;
//
//
// public function removePhotoBanner(PhotoBanner $photoBanner): NestedBanner
//
// $this->photoBanners->removeElement($photoBanner);
//
// return $this;
//
//
// public function removeVideoBanner(VideoBanner $videoBanner): NestedBanner
//
// $this->videoBanners->removeElement($videoBanner);
//
// return $this;
//
//
// public function removePromoBlockBanner(PromoBlockBanner $promoBlockBanner): NestedBanner
//
// $this->promoBlockBanners->removeElement($promoBlockBanner);
//
// return $this;
//
public function remove($param)
dd($param);
<?php
namespace App\Cms\Entity\Banner;
use Symfony\Component\Validator\Constraints as Assert;
use Symfony\Component\HttpFoundation\File\File;
use Doctrine\ORM\Mapping as ORM;
use Vich\UploaderBundle\Mapping\Annotation as Vich;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Collection;
use App\Cms\Entity\Banner\NestedBanner;
/**
*
* @ORM\Entity(repositoryClass="App\Cms\Repository\Banner\BannerRepository")
* @ORM\Table(name="banner")
* @Vich\Uploadable()
*/
class Banner
/**
* @ORM\Id()
* @ORM\GeneratedValue()
* @ORM\Column(type="integer")
*/
private $id;
/**
* @ORM\Column(name="title", type="string", length=255)
*/
private $title;
/**
* @var File
* @Vich\UploadableField(mapping="banner_background_image", fileNameProperty="backgroundImageName")
* @Assert\Image(
* mimeTypes = "image/jpeg", "image/png", "image/svg+xml",
* mimeTypesMessage = "Дозволені тільки формати (jpg,png,svg)",
* maxSize = "2M",
* maxSizeMessage = "Максимальний розмір 2Mb"
* )
*/
private $backgroundImage;
/**
* @var string
* @ORM\Column(type="string", nullable=true)
*/
private $backgroundImageName;
/**
* @ORM\Column(name="link", type="string", length=255)
*/
private $link;
/**
* @var $nestedBanner
*
* @ORM\ManyToOne(
* targetEntity="App\Cms\Entity\Banner\NestedBanner",
* inversedBy="banners")
*
*/
private $nestedBanner;
public function __construct()
/**
*
* @return type
*/
public function getId()
return $this->id;
/**
*
* @return type
*/
public function getTitle(): ?string
return $this->title;
/**
*
* @return type
*/
public function getName(): ?string
return $this->getBackgroundImageName();
/**
*
* @return type
*/
public function getBackgroundImage(): ?File
return $this->backgroundImage;
/**
*
* @return type
*/
public function getBackgroundImageName()
return $this->backgroundImageName;
/**
*
* @return type
*/
public function getLink()
return $this->link;
/**
*
* @return array
*/
public function getNestedBanner(): ?NestedBanner
return $this->nestedBanner;
/**
*
* @param type $id
*/
public function setId(int $id)
$this->id = $id;
/**
*
* @param string $title
*/
public function setTitle(string $title)
$this->title = $title;
/**
*
* @param string $backgroundImage
*/
public function setBackgroundImage(File $backgroundImage)
$this->backgroundImage = $backgroundImage;
if(!$this->backgroundImageName)
$this->backgroundImageName = $backgroundImage->getClientOriginalName();
/**
*
* @param string $backgroundImageName
*/
public function setBackgroundImageName($backgroundImageName)
$this->backgroundImageName = $backgroundImageName;
/**
*
* @param string $link
*/
public function setLink(string $link)
$this->link = $link;
/**
*
* @param NestedBanner $nestedBanner
*/
public function setNestedBanner(NestedBanner $nestedBanner)
$this->nestedBanner = $nestedBanner;
return $this;
/**
* @return string
*/
public function __toString(): string
return $this->title ?: '';
【问题讨论】:
【参考方案1】:考虑看看奏鸣曲的saving hooks。
您似乎已经在使用preUpdate()
函数,并且可以利用preRemove()
函数来实现您正在寻找的内容。
您可能还必须从您的实体中删除 onDelete="CASCADE"
。
【讨论】:
是的,preUpdate 工作正常,但 preRemove - 不行。删除了 onDelete="CASCADE" 但现在当我试图从管理员中删除它时,表单不会保存关系更改。 在 preRemove 中,您是否尝试添加类似$parent->getChildren();
的内容,然后循环遍历它们并将每个子对象的父对象设置为 NULL?以上是关于Symfony 4 + 奏鸣曲管理包 + 关系。表单正在删除子项,但不仅是 parentId的主要内容,如果未能解决你的问题,请参考以下文章