3

我有两个实体(简化):

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

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

数据库中可以有多个EncryptedMasterKeys ExchangeFile。如果ExchangeFile删除,所有相关的加密MasterKeys都将被删除(orphanRemoval=truecascade={"persist", "remove"}确保是这种情况)。到现在为止还挺好。

现在由于实际文件在硬盘上是加密的,因此必须至少有一个EncryptedMasterKey文件才能解密。所以当 aEncryptedMasterKey被删除并且我发现它是它的最后一个时ExchangeFile,我也必须删除它,ExchangeFile 因为它不能再被解密了。一个ExchangeFile人不能没有至少一个EncryptedMasterKey

我如何实现这一目标?@ORM\PreRemoveEncryptedMasterKey课堂上并没有真正帮助我,因为我无权访问实体管理器:

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?
    }
}

有什么优雅的解决方案吗?

谢谢你的时间。

4

1 回答 1

4

您可以使用事件订阅者并创建如下类:

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());
            }
        }
    }
}

你可以阅读更多关于如何在 Symfony 2 的特定案例中注册订阅者的文档

于 2013-02-15T16:42:53.987 回答