I have two entities (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 EncryptedMasterKeys for one ExchangeFile in the database. If the ExchangeFile is deleted, all related encrypted MasterKeys are deleted (orphanRemoval=true and cascade={"persist", "remove"} make sure this is the case). So far, so good.
Now as the actual file lies encrypted on the hard disk, there must be at least one EncryptedMasterKey so that the file can be decrypted. So when a EncryptedMasterKey is deleted and I discover that it is the last one for it's ExchangeFile, I also have to delete the ExchangeFile because it cannot be decrypted any more. An ExchangeFile cannot live without at least one EncryptedMasterKey.
How do I achieve this? @ORM\PreRemove in the EncryptedMasterKey class does'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 any elegant solution to this?
Thanks for your time.
You can use an event subscriber and create a class like 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 the particular case of Symfony 2 on the documentation for it.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With