/**
* Deletes a document as part of the current unit of work.
*
* This method is internally called during delete() cascades as it tracks
* the already visited documents to prevent infinite recursions.
*
* @param object $document The document to delete.
* @param array $visited The map of the already visited documents.
* @throws MongoDBException
*/
private function doRemove($document, array &$visited)
{
$oid = spl_object_hash($document);
if (isset($visited[$oid])) {
return;
// Prevent infinite recursion
}
$visited[$oid] = $document;
// mark visited
/* Cascade first, because scheduleForDelete() removes the entity from
* the identity map, which can cause problems when a lazy Proxy has to
* be initialized for the cascade operation.
*/
$this->cascadeRemove($document, $visited);
$class = $this->dm->getClassMetadata(get_class($document));
$documentState = $this->getDocumentState($document);
switch ($documentState) {
case self::STATE_NEW:
case self::STATE_REMOVED:
// nothing to do
break;
case self::STATE_MANAGED:
if (!empty($class->lifecycleCallbacks[Events::preRemove])) {
$class->invokeLifecycleCallbacks(Events::preRemove, $document);
}
if ($this->evm->hasListeners(Events::preRemove)) {
$this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($document, $this->dm));
}
$this->scheduleForDelete($document);
break;
case self::STATE_DETACHED:
throw MongoDBException::detachedDocumentCannotBeRemoved();
default:
throw MongoDBException::invalidDocumentState($documentState);
}
}