src/CascadeRemoveTrait.php
private function findCascadeDetachableEntities(EntityManager $em,
                                                   CascadeRemovableInterface $entity,
                                                   &$visited = [],
                                                   $depth = 0)
    {
        $id            = $em->getUnitOfWork()->getEntityIdentifier($entity);
        $key           = serialize([get_class($entity), $id]);
        $visited[$key] = $entity;
        
        $entities = $entity->getCascadeRemoveableEntities();
        foreach ($entities as $subEntity) {
            $id  = $em->getUnitOfWork()->getEntityIdentifier($subEntity);
            $key = serialize([get_class($subEntity), $id]);
            if (array_key_exists($key, $visited)) {
                //mdebug(
                //    "%sSkipping %s %d when detaching %s %d",
                //    str_repeat(' ', $depth * 4),
                //    get_class($subEntity),
                //    $subEntity->getId(),
                //    get_class($entity),
                //    $entity->getId()
                //);
                continue;
            }
            //mdebug(
            //    "%sCascade removing %s %d when removing %s %d",
            //    str_repeat(' ', $depth * 4),
            //    get_class($subEntity),
            //    $subEntity->getId(),
            //    get_class($entity),
            //    $entity->getId()
            //);
            
            if ($subEntity instanceof CascadeRemovableInterface) {
                $this->findCascadeDetachableEntities($em, $subEntity, $visited, $depth + 1);
            }
            else {
                $visited[$key] = $subEntity;
            }
        }
    }
private function findCascadeDetachableEntities(EntityManager $em,
                                                   CascadeRemovableInterface $entity,
                                                   &$visited = [],
                                                   $depth = 0)
    {
        $id            = $em->getUnitOfWork()->getEntityIdentifier($entity);
        $key           = serialize([get_class($entity), $id]);
        $visited[$key] = $entity;
        
        $entities = $entity->getCascadeRemoveableEntities();
        foreach ($entities as $subEntity) {
            $id  = $em->getUnitOfWork()->getEntityIdentifier($subEntity);
            $key = serialize([get_class($subEntity), $id]);
            if (array_key_exists($key, $visited)) {
                //mdebug(
                //    "%sSkipping %s %d when detaching %s %d",
                //    str_repeat(' ', $depth * 4),
                //    get_class($subEntity),
                //    $subEntity->getId(),
                //    get_class($entity),
                //    $entity->getId()
                //);
                continue;
            }
            //mdebug(
            //    "%sCascade removing %s %d when removing %s %d",
            //    str_repeat(' ', $depth * 4),
            //    get_class($subEntity),
            //    $subEntity->getId(),
            //    get_class($entity),
            //    $entity->getId()
            //);
            
            if ($subEntity instanceof CascadeRemovableInterface) {
                $this->findCascadeDetachableEntities($em, $subEntity, $visited, $depth + 1);
            }
            else {
                $visited[$key] = $subEntity;
            }
        }
    }
private function findCascadeDetachableEntities ( EntityManager $ em , CascadeRemovableInterface $ entity , & $ visited = [ ] , $ depth = 0 ) { $ id = $ em -> getUnitOfWork ( ) -> getEntityIdentifier ( $ entity ) ; $ key = serialize ( [ get_class ( $ entity ) , $ id ] ) ; $ visited [ $ key ] = $ entity ; $ entities = $ entity -> getCascadeRemoveableEntities ( ) ; foreach ( $ entities as $ subEntity ) { $ id = $ em -> getUnitOfWork ( ) -> getEntityIdentifier ( $ subEntity ) ; $ key = serialize ( [ get_class ( $ subEntity ) , $ id ] ) ; if ( array_key_exists ( $ key , $ visited ) ) { //mdebug( //    "%sSkipping %s %d when detaching %s %d", //    str_repeat(' ', $depth * 4), //    get_class($subEntity), //    $subEntity->getId(), //    get_class($entity), //    $entity->getId() //); continue ; } //mdebug( //    "%sCascade removing %s %d when removing %s %d", //    str_repeat(' ', $depth * 4), //    get_class($subEntity), //    $subEntity->getId(), //    get_class($entity), //    $entity->getId() //); if ( $ subEntity instanceof CascadeRemovableInterface ) { $ this -> findCascadeDetachableEntities ( $ em , $ subEntity , $ visited , $ depth + 1 ) ; } else { $ visited [ $ key ] = $ subEntity ; } } }
Detaches associated entities from EntityManager and Cache. Normally these entities should either be deleted
or updated in database in post-remove phase.

@param EntityManager             $em
@param CascadeRemovableInterface $entity
@param array                     $visited visited entities
@param int                       $depth
Detaches associated entities from EntityManager and Cache . Normally these entities should either be deleted or updated in database in post - remove phase .