简体   繁体   English

Symfony 4 + 奏鸣曲管理包 + 关系。 表单正在删除子项,但不仅是 parentId

[英]Symfony 4 + sonata admin bundle + relations. Form is deleting children but not only parentId

Good day everyone.今天是个好日子。 I encounter some problem.我遇到了一些问题。 I have sonata admin + symfony 4 + some entities with manytoone relations.我有奏鸣曲管理员 + symfony 4 + 一些具有多面关系的实体。 I have 3 simple tables named banner videobanner photobanner and now i want to create admin part which will be created from 1 2 or 3 simple banners video banners or photobbanners.我有 3 个名为banner videobanner photobanner 的简单表格,现在我想创建管理部分,它将由 1 2 或 3 个简单的横幅视频横幅或 photobbanner 创建。 It is almost done but the form have some bugs, I can create simple banner and it is ok record created sucessfully but parentId is empty because it does not have any parents for now but later when im set in in admin parentId is createing in child table but later when im trying to delete the relation sonata admin deletes it with a child record.几乎完成了,但是表单有一些错误,我可以创建简单的横幅,并且可以成功创建记录,但是 parentId 是空的,因为它现在没有任何父母,但后来当我在管理员中设置时 parentId 正在子表中创建但后来当我试图删除关系奏鸣曲管理员用子记录删除它。 but i want sonata admin to delete only parentId child record must stay with parentId = NULL.但我希望奏鸣曲管理员只删除 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 ?: '';
    }
}

Consider taking a look at sonata's saving hooks .考虑看看奏鸣曲的储蓄钩子

It looks like you're already using the preUpdate() function and could utilize the preRemove() function to achieve what you are looking for.看起来您已经在使用preUpdate() function 并且可以利用preRemove() function 来实现您正在寻找的内容。

You'll also likely have to remove onDelete="CASCADE" from your entity.您可能还必须从您的实体中删除onDelete="CASCADE"

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM