3

私は2つのエンティティを持っています(簡略化):

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

EncryptedMasterKeyデータベース内の 1 つに対して多数の が存在する場合がありExchangeFileます。がExchangeFile削除されると、関連するすべての暗号化MasterKeysが削除されます (これが事実であることorphanRemoval=truecascade={"persist", "remove"}確認してください)。ここまでは順調ですね。

実際のファイルはハードディスク上で暗号化されているため、ファイルを復号化できるように少なくとも 1 つEncryptedMasterKey存在する必要があります。したがって、 aEncryptedMasterKeyが削除され、それが の最後のものであることがわかった場合は、これ以上復号化できないため、ExchangeFileも削除する必要があります。少なくとも 1 つがなければ生きていけません。ExchangeFile ExchangeFileEncryptedMasterKey

どうすればこれを達成できますか? @ORM\PreRemoveエンティティマネージャーにアクセスできないため、EncryptedMasterKeyクラス内ではあまり役に立ちません。

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 に答える