Symfony Doctrine:一对多关系正在删除父实体

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Symfony Doctrine:一对多关系正在删除父实体相关的知识,希望对你有一定的参考价值。

我有父母和子女实体。删除所有子实体后,symfony也会删除我的父实体。我不喜欢这种行为,只要有一些孩子,父母实体就必须存在。这是我父母的代码:

    /**
     * @OneToMany(targetEntity="Gallery", mappedBy="promotion", cascade={"persist", "remove"})
     */
    private $galleries;

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

    public function getGalleries() {
        return $this->galleries;
    }

    public function addGallery($gallery)
    {
        $gallery->setPromotion($this);
        $this->galleries[] = $gallery;

        return $this;
    }

    public function removeGallery($gallery)
    {
        $gallery->setPromotion(null);
        $this->galleries->removeElement($gallery);
    }

在这里为孩子:

    /**
     * @ManyToOne(targetEntity="Promotion", inversedBy="galleries")
     */

    private $promotion;

我不知道该怎么办,我已经花了好几个小时。

它由易管理包处理,所以它不会帮助你:

namespace AppBundleController;

use JavierEguiluzBundleEasyAdminBundleEventEasyAdminEvents;
use SymfonyComponentSecurityAclExceptionException;
use AppBundleEntityPromotion;
use SymfonyComponentHttpFoundationJsonResponse;

class PromotionController extends PageController {
    protected $folder = 'promotions';
    protected $htmlFileName = 'default-template.html';

    protected function rearangeAction() {
        $ids = json_decode($this->request->get('ids'));
        $order = 1;

        foreach($ids as $id) {            
            $this->em->createQuery('UPDATE AppBundle:Promotion p SET p.order = :order WHERE p.id = :id')
                ->setParameter('order', $order++)
                ->setParameter('id', $id)
                ->execute();
        }

        return $this->redirectToRoute('easyadmin', $this->prepareRouteParams());
    }

    protected function checkFolderAction() {        
        $row = $this->em->createQuery('SELECT p FROM AppBundle:Promotion p WHERE p.language = :language AND p.subfolder = :subfolder')
                ->setParameter('language', $this->language)
                ->setParameter('subfolder', $this->request->get('subfolder'))
                ->getOneOrNullResult();

        if($row) {
            return new JsonResponse(array('duplicity' => 1));
        } else {
            return new JsonResponse(array('duplicity' => 0));
        }
    }

    protected function deleteFiles($databaseSubFolders) {
        $mainFolder = $this->baseDir.'/'.$this->folder.'/'.$this->language;

        $databaseSubFolders[] = '..';
        $databaseSubFolders[] = '.';

        $subFolders = array_diff(scandir($mainFolder), $databaseSubFolders);

        foreach($subFolders as $subFolder) {
            $this->deleteFolder($mainFolder.'/'.$subFolder);
        }
    }

    protected function exportAction() {
        $query = $this->em->createQuery('SELECT p FROM AppBundle:Promotion p WHERE p.language = :language')
                ->setParameter('language', $this->language);

        $subFolders = array();

        foreach($query->getArrayResult() as $key => $val) {
            $subFolders[] = $val['subfolder'];

            //  pridanie novych a uprava starych

            $image = basename($val['headerImage']);
            $imageName = substr($image, 0 ,strpos($image,'.'));

            $all = '<div class="header">
                        <div class="row">
                            <h2>
                                '.$val['headerTitle'].'
                            </h2>
                            <p>
                                '.$val['headerTeaser'].'
                            </p>
                        </div>
                    </div><img src="{{::promo.imgPath}}/'.$image.'" alt="'.$imageName.'">';

            $all .= $this->changeMarkdownToHtml($val['html']);
            $all .= $this->changeMarkdownToHtml($val['terms']);

            file_put_contents($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$val['subfolder'].'/html/'.$val['filename'], $all);
        }

        //  zmazanie starych zloziek

        $this->deleteFiles($subFolders);        

        parent::exportAction();

        return $this->redirectToRoute('easyadmin', $this->prepareRouteParams());
    }

    private function actualImage($id, $i) {
        $row = $this->em->createQuery('SELECT p FROM AppBundle:Promotion p WHERE p.id = :id')
                ->setParameter('id', $id)
                ->getOneOrNullResult();

        return call_user_func_array(array($row,'getImage'.$i), array());
    }

    protected function preDeleteEntity($id) {
        //  mazanie obrazkov


    }

    protected function preSearchEntity($entity) {
        $entity['search']['dql_filter'] = "entity.language = '".$this->language."'";

        return $entity;
    }

    protected function prePersistEntity($entity) {
        //  ukladanie dalsich dat

        $entity->setLanguage($this->language);
        $entity->setFilename($this->htmlFileName);

        $row = $this->em->createQuery('SELECT MAX(p.order)+1 FROM AppBundle:Promotion p')
                ->getOneOrNullResult();

        $entity->setOrder($row[1]);

        return $entity;
    }

    protected function postPersistEntity($entity) {
        if(!is_dir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder())) {                
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder());
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'header');
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'html');
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'img');
        }

        //  presun obrazkov

        $images = array();

        foreach($entity->getGalleries()->getSnapshot() as $snapshot) {
            $image = $snapshot->getImage();

            $from = $this->get('kernel')->getRootDir().'/../web/uploads/temp/'.basename($image);
            $to = $this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/img/'.$image;

            $this->copyFile($from, $to);

            $images[] = $image;
        }

        $getImage = $entity->getHeaderImage();

        $from = $this->get('kernel')->getRootDir().'/../web/uploads/temp/'.basename($getImage);
        $to = $this->baseDir.'/'.$this->folder.'/'.$this->language.$getImage;

        $this->copyFile($from, $to);

        $entity->setHtml($this->replaceImages($entity->getHtml(), $images));

        return $entity;
    }

    protected function preRemoveEntity($entity) {
        //if($_POST['_method'] != 'DELETE') {
//            var_dump($entity);
//            die();
        //}

        return $entity;
    }

    protected function editAction() {    
        $id = $this->request->query->get('id');

        $this->dispatch(EasyAdminEvents::PRE_EDIT);
        $this->executeDynamicMethod('preEdit<EntityName>Entity', array($id));

        $easyadmin = $this->request->attributes->get('easyadmin');
        $entity = $easyadmin['item'];        

        if ($this->request->isXmlHttpRequest() && $property = $this->request->query->get('property')) {
            $newValue = 'true' === mb_strtolower($this->request->query->get('newValue'));
            $fieldsMetadata = $this->entity['list']['fields'];

            if (!isset($fieldsMetadata[$property]) || 'toggle' !== $fieldsMetadata[$property]['dataType']) {
                throw new RuntimeException(sprintf('The type of the "%s" property is not "toggle".', $property));
            }

            $this->updateEntityProperty($entity, $property, $newValue);

            return new Response((string) $newValue);
        }

        $fields = $this->entity['edit']['fields'];

        $editForm = $this->executeDynamicMethod('create<EntityName>EditForm', array($entity, $fields));

        $deleteForm = $this->createDeleteForm($this->entity['name'], $id);

        //  kontrola pre presun

        $row = $this->em->createQuery('SELECT p FROM AppBundle:Promotion p WHERE p.id = :id')
                    ->setParameter('id', $id)
                    ->getOneOrNullResult();

        $previousSubfolder = $row->getSubfolder();

        $editForm->handleRequest($this->request);

        if ($editForm->isSubmitted() && $editForm->isValid()) {
            $this->dispatch(EasyAdminEvents::PRE_UPDATE, array('entity' => $entity));            
            $entity = $this->executeDynamicMethod('preUpdate2<EntityName>Entity', array($entity,$previousSubfolder));

            $this->em->flush();

            $this->dispatch(EasyAdminEvents::POST_UPDATE, array('entity' => $entity));            
            $entity = $this->executeDynamicMethod('postUpdate2<EntityName>Entity', array($entity,$previousSubfolder));

            $refererUrl = $this->request->query->get('referer', '');           

            return !empty($refererUrl)
                ? $this->redirect(urldecode($refererUrl))
                : $this->redirect($this->generateUrl('easyadmin', array('action' => 'list', 'entity' => $this->entity['name'])));
        }

        $this->dispatch(EasyAdminEvents::POST_EDIT);        
        $entity = $this->executeDynamicMethod('postEdit<EntityName>Entity', array($entity));

        return $this->render($this->entity['templates']['edit'], array(
            'form' => $editForm->createView(),
            'entity_fields' => $fields,
            'entity' => $entity,
            'delete_form' => $deleteForm->createView(),
        ));
    }

    protected function preUpdate2Entity($entity, $previousSubfolder) {


//        if($_POST['delete_form']['_easyadmin_delete_flag'] == 1) {
//            $this->em->createQuery('DELETE FROM AppBundle:Gallery g WHERE g.promotion = :id')
//                    ->setParameter('id', $id)
//                    ->execute();
//        }


        $images = array();        

        foreach($entity->getGalleries()->getSnapshot() as $snapshot) {
            $image = $snapshot->getImage();

            $images[] = $image;
        }



        $entity->setHtml($this->replaceImages($entity->getHtml(), $images));

        return $entity;
    }

    protected function postUpdate2Entity($entity, $previousSubfolder) {
        if(!is_dir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder())) {                
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder());
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'header');
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'html');
            mkdir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/'.'img');
        }

        //  presun obrazkov

        $images = array();

        foreach($entity->getGalleries()->getSnapshot() as $snapshot) {
            $image = $snapshot->getImage();

            $from = $this->get('kernel')->getRootDir().'/../web/uploads/temp/'.basename($image);
            $to = $this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/img/'.$image;

            if(!file_exists($from)) {                  
                $from = $this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$previousSubfolder.'/img/'.$image;
            }

            $this->copyFile($from, $to);
            $images[] = $image;
        }

        //  zmazanie obrazkov

        $folderImages = array_diff(scandir($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$previousSubfolder.'/img/'), array('..', '.'));

        foreach($folderImages as $folderImage) {
            if(!in_array($folderImage, $images)) {
                unlink($this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$previousSubfolder.'/img/'.$folderImage);
            }
        }

        $getImage = $entity->getHeaderImage();

        $from = $this->get('kernel')->getRootDir().'/../web/uploads/temp/'.basename($getImage);

        if(!file_exists($from)) {
            $from = $this->baseDir.'/'.$this->folder.'/'.$this->language.$getImage;
        }

        $to = $this->baseDir.'/'.$this->folder.'/'.$this->language.'/'.$entity->getSubfolder().'/header/'.basename($getImage);

        $this->copyFile($from, $to);

        return $entity;
    }

    protected function postEditEntity($entity) {
        //  cesta pre obrazky        

        $entity->setHeaderImage(null, '/uploads/'.$this->container->getParameter('repo.folder').'/'.$this->folder.'/'.$this->language.$entity->getHeaderImage());

        return $entity;
    }

    protected function preListEntity($entity) {
        $entity['list']['dql_filter'] = "entity.language = '".$this->language."'";

        return $entity;
    }

    protected function postListEntity($fields) {
        //  cesta pre obrazky        

        $fields['headerImage']['base_path'] = '/uploads/'.$this->container->getParameter('repo.folder').'/'.$this->folder.'/'.$this->language;

        return $fields;
    }

    protected function postSearchEntity($fields) {
        //  cesta pre obrazky

        $fields['headerImage']['base_path'] = '/uploads/'.$this->container->getParameter('repo.folder').'/'.$this->folder.'/'.$this->language;

        return $fields;
    }
}
答案

尝试删除级联注释。其余的看起来不错。

以上是关于Symfony Doctrine:一对多关系正在删除父实体的主要内容,如果未能解决你的问题,请参考以下文章

Symfony 2 与 Doctrine 中的一对多关系

Doctrine 对一对多关系进行了许多查询

symfony doctrine验证实体关系错误

Symfony2 - 具有一对一关系的 Doctrine Save 实体

一对多还是多对多?

使用 Doctrine 和 Symfony2 查询多对多关系