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.
source to share
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.
source to share