Search code examples
phpormdoctrineconcrete5

doctrine deleting has to be done twice


I have the following DB structure and relations:

Posts -> OneToMany,cascade={"persist"} -> Replies -> OneToMany,cascade={"persist"} -> Files entities + files on disk -> event to delete files entities

Posts -> OneToMany,cascade={"persist"} -> Files entities + files on disk -> event to delete files entities

The thing about files is:

  • deleting files entity (from application) deletes file on disk
  • deleting file on disk (from file manager) fires an event deleting files entity

What I need is if a post is deleted, it cascades all the way to deleting replies, file entities and its files on disk. The chain of events is:

  1. page controller:
post->remove();
  1. Post class:
remove()
{
    PostFile::deleteFiles($this);
    Reply::deleteFiles($this);
    $em->remove($this);
    $em->flush();
}

  1. PostFile:
deleteFiles($post)
{
    $files = $post->getFiles()->toArray();
    foreach ($files as $file) {
        $f->delete();
    }
}
  1. Reply:
deleteFiles($post)
{
    $replies = $post->getReplies()->toArray();
    foreach ($replies as $reply) {
        if ($reply) {
            ReplyFile::deleteFiles($reply);
        }
    }
}
  1. ReplyFile:
deleteFiles($reply)
{
    $files = $reply->getFiles()->toArray();
    foreach ($files as $file) {
        $f->delete();
    }
}
  1. File deletion event:
Events::addListener('on_file_delete', function($event) {
    $f = $event->getFileObject();
    $fid = $file->getFileID();
    $fpf = PostFile::getByFileID($fid);
    $fpf->delete();
    $fpmf = ReplyFile::getByFileID($fid);
    $fpmf->delete();
});

Everything down the chain works fine, e.g. everything gets deleted, except for the post itself which doesn't get deleted, it has to be deleted twice. Why can that be?


Solution

  • Changing OneToMany,cascade={"persist"} to OneToMany,cascade={"remove"} seemed to have fixed it, now everything gets deleted on first try