Doctrine of the "reverse" treatment of doctrine

I have two objects (simplified):

class EncryptedMasterKey {
    /**
     * @ORM\ManyToOne(targetEntity="ExchangeFile", inversedBy="encryptedMasterKeys")
     * @ORM\JoinColumn(name="exchange_file_id", referencedColumnName="id")
     *
     * @var ExchangeFile
     */
    protected $exchangeFile;
}

      

and

class ExchangeFile {
    /**
     * @ORM\OneToMany(targetEntity="EncryptedMasterKey", mappedBy="exchangeFile", orphanRemoval=true, cascade={"persist", "remove"})
     */
    protected $encryptedMasterKeys;
}

      

There can be many EncryptedMasterKey

for one in the database ExchangeFile

. If ExchangeFile

removed, all associated encrypted ones MasterKeys

are removed ( orphanRemoval=true

and cascade={"persist", "remove"}

make sure they are). So far so good.

Now that the actual file is encrypted on the hard drive, there must be at least oneEncryptedMasterKey

in order for the file to be decrypted. So when a EncryptedMasterKey

is removed and I find it is the last one for it ExchangeFile

, I also need to remove ExchangeFile

it because it can no longer be decrypted . ExchangeFile

can't live without at least one EncryptedMasterKey

.

How can I achieve this? @ORM\PreRemove

in class EncryptedMasterKey

doesn't really help me because I don't have access to the entity manager:

class EncryptedMasterKey {
    //...
    /** @ORM\PreRemove */
    public function removeOrphanExchangeFile()
    {
        if ($this->exchangeFile->isTheOnlyMasterKey($this))
            // I don't have access to the Entity Manager,
            // so how do I delete the ExchangeFile?
    }
}

      

Is there an elegant solution for this?

Thank you for your time.

+3


source to share


1 answer


You can use an event subscriber and create a class like the following:

class MyEncryptedMasterSubscriber implements \Doctrine\Common\EventSubscriber
{
    public function getSubscribedEvents()
    {
        return array(\Doctrine\ORM\Events::onFlush);
    }

    public function onFlush(\Doctrine\ORM\Events\OnFlushEventArgs $eventArgs)
    {
        $uow = $eventArgs->getEntityManager()->getUnitOfWork();


        foreach ($uow->getScheduledEntityDeletions() AS $entity) {
            if (
                $entity instanceof EncryptedMasterKey 
                && $entity->getExchangeFile()->isTheOnlyMasterKey($entity)
            ) {
                $uow->scheduleForDelete($entity->getExchangeFile());
            }
        }
    }
}

      



You can read more about how to register subscribers in a specific Symfony 2 case on the documentation for it.

+4


source







All Articles