Cascades a refresh operation to associated documents.

@param object $document
@param array  $visited

@return void
438330
private function cascadeRefresh($document, array &$visited)
    {
        $class = $this->dm->getClassMetadata(get_class($document));

        $associationMetadata = array_filter(
            $class->associationMetadata,
            function ($assoc) {
                return $assoc->isCascadeRefresh;
            }
        );

        foreach ($associationMetadata as $mapping) {
            $relatedDocuments = $class->getPropertyMetadata($mapping->name)->getValue($document);
            if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) {
                if ($relatedDocuments instanceof PersistentCollectionInterface) {
                    // Unwrap so that foreach() does not initialize
                    $relatedDocuments = $relatedDocuments->unwrap();
                }
                foreach ($relatedDocuments as $relatedDocument) {
                    $this->doRefresh($relatedDocument, $visited);
                }
            } elseif ($relatedDocuments !== null) {
                $this->doRefresh($relatedDocuments, $visited);
            }
        }
    }
682832
public function setDocumentChangeSet(object $document, array $changeset) : void
    {
        $this->documentChangeSets[spl_object_hash($document)] = $changeset;
    }
327837
private function cascadePersist($entity, array &$visited)
    {
        $class = $this->em->getClassMetadata(get_class($entity));

        if ($entity instanceof GhostObjectInterface && ! $entity->isProxyInitialized()) {
            // nothing to do - proxy is not initialized, therefore we don't do anything with it
            return;
        }

        foreach ($class->getDeclaredPropertiesIterator() as $association) {
            if (! ($association instanceof AssociationMetadata && in_array('persist', $association->getCascade(), true))) {
                continue;
            }

            /** @var AssociationMetadata $association */
            $relatedEntities = $association->getValue($entity);
            $targetEntity    = $association->getTargetEntity();

            switch (true) {
                case $relatedEntities instanceof PersistentCollection:
                    // Unwrap so that foreach() does not initialize
                    $relatedEntities = $relatedEntities->unwrap();
                    // break; is commented intentionally!

                case $relatedEntities instanceof Collection:
                case is_array($relatedEntities):
                    if (! ($association instanceof ToManyAssociationMetadata)) {
                        throw ORMInvalidArgumentException::invalidAssociation(
                            $this->em->getClassMetadata($targetEntity),
                            $association,
                            $relatedEntities
                        );
                    }

                    foreach ($relatedEntities as $relatedEntity) {
                        $this->doPersist($relatedEntity, $visited);
                    }

                    break;

                case $relatedEntities !== null:
                    if (! $relatedEntities instanceof $targetEntity) {
                        throw ORMInvalidArgumentException::invalidAssociation(
                            $this->em->getClassMetadata($targetEntity),
                            $association,
                            $relatedEntities
                        );
                    }

                    $this->doPersist($relatedEntities, $visited);
                    break;

                default:
                    // Do nothing
            }
        }
    }
310522
public function refresh(Aggregate $entity)
    {
        $this->cache[$entity->getEntityKeyValue()] = $this->transform($entity);
    }
187017
public function add($documents)
    {

        $pendingRemove = $this->getRemove();
        if ($this->getRemove()) {
            if ($this->all()) {
                throw new \RuntimeException('Adding to group with pending remove is not permitted');
            } else {
                $this->clearAdd();
                $this->clearRemove();
                $this->saved = array();
            }
        }
        if (!is_array($documents)) {
            $documents = array($documents);
        }

        $add =& $this->getArchive()->getByRef('add', array());
        foreach ($documents as $document) {
            $add[] = $document;
        }
    }
343330
private function cascadePreRemove(ClassMetadata $class, $document)
    {
        $hasPreRemoveListeners = $this->evm->hasListeners(Events::preRemove);

        foreach ($class->fieldMappings as $mapping) {
            if (isset($mapping['embedded'])) {
                $value = $class->reflFields[$mapping['fieldName']]->getValue($document);
                if ($value === null) {
                    continue;
                }
                if ($mapping['type'] === 'one') {
                    $value = array($value);
                }
                foreach ($value as $entry) {
                    $entryClass = $this->dm->getClassMetadata(get_class($entry));
                    if ( ! empty($entryClass->lifecycleCallbacks[Events::preRemove])) {
                        $entryClass->invokeLifecycleCallbacks(Events::preRemove, $entry);
                    }
                    if ($hasPreRemoveListeners) {
                        $this->evm->dispatchEvent(Events::preRemove, new LifecycleEventArgs($entry, $this->dm));
                    }
                    $this->cascadePreRemove($entryClass, $entry);
                }
            }
        }
    }
252748
public function updateReferenceCache(Codebase $codebase, array $visited_files)
    {
        foreach ($visited_files as $file => $_) {
            $all_file_references = array_unique(
                array_merge(
                    isset(self::$file_references[$file]['a']) ? self::$file_references[$file]['a'] : [],
                    $this->calculateFilesReferencingFile($codebase, $file)
                )
            );

            $inheritance_references = array_unique(
                array_merge(
                    isset(self::$file_references[$file]['i']) ? self::$file_references[$file]['i'] : [],
                    $this->calculateFilesInheritingFile($codebase, $file)
                )
            );

            self::$file_references[$file] = [
                'a' => $all_file_references,
                'i' => $inheritance_references,
            ];
        }

        if ($this->cache) {
            $this->cache->setCachedFileReferences(self::$file_references);
            $this->cache->setCachedFileClassReferences(self::$file_references_to_classes);
            $this->cache->setCachedMethodMemberReferences(self::$method_references_to_class_members);
            $this->cache->setCachedFileMemberReferences(self::$file_references_to_class_members);
            $this->cache->setCachedMethodMissingMemberReferences(self::$method_references_to_missing_class_members);
            $this->cache->setCachedFileMissingMemberReferences(self::$file_references_to_missing_class_members);
            $this->cache->setCachedMixedMemberNameReferences(self::$references_to_mixed_member_names);
            $this->cache->setCachedMethodParamUses(self::$method_param_uses);
            $this->cache->setCachedIssues(self::$issues);
            $this->cache->setFileMapCache(self::$file_maps);
            $this->cache->setTypeCoverage(self::$mixed_counts);
            $this->cache->setAnalyzedMethodCache(self::$analyzed_methods);
        }
    }
305004
protected function hasCircularReferences($parent, $visited = array()){
		foreach($parent->subqueries as $child){
			if(isset($visited[spl_object_hash($child)]))
				return true;
			$visited[spl_object_hash($child)] = true;
			if($this->hasCircularReferences($child, $visited))
				return true;
			array_pop($visited);
		}
		return false;
	}
19194
public function persist($document)
    {
        $documentArray = $this->converter->convertToArray($document);
        $type = $this->getMetadataCollector()->getDocumentType(get_class($document));

        $this->bulk('index', $type, $documentArray);
    }
273004
private function doRefresh($document, array &$visited)
    {
        $oid = spl_object_hash($document);
        if (isset($visited[$oid])) {
            return; // Prevent infinite recursion
        }

        $visited[$oid] = $document; // mark visited

        $class = $this->dm->getClassMetadata(get_class($document));

        if (!$class->isEmbeddedDocument) {
            if ($this->getDocumentState($document) !== self::STATE_MANAGED) {
                throw new \InvalidArgumentException('Document is not MANAGED.');
            }

            $identifier = $this->documentIdentifiers[$oid];
            $this->getDocumentPersister($class->name)->refresh($identifier, $document);
        }

        $this->cascadeRefresh($document, $visited);
    }
519602
public function refresh(object $document) : void
    {
        assert($this->collection instanceof Collection);
        $query = $this->getQueryForDocument($document);
        $data  = $this->collection->findOne($query);
        if ($data === null) {
            throw MongoDBException::cannotRefreshDocument();
        }
        $data = $this->hydratorFactory->hydrate($document, (array) $data);
        $this->uow->setOriginalDocumentData($document, $data);
    }
66038
private function doDetach($object, array &$visited)
    {
        $oid = spl_object_hash($object);
        if (isset($visited[$oid])) {
            return;
        }

        $visited[$oid] = true;

        $state = $this->getDocumentState($object, self::STATE_DETACHED);
        if (self::STATE_MANAGED !== $state) {
            return;
        }

        unset(
            $this->documentStates[$oid],
            $this->objects[$oid],
            $this->originalDocumentData[$oid]
        );

        $this->removeFromIdentityMap($object);
        $this->cascadeDetach($object, $visited);
    }
1284596
private function cascadePreUpdate(ClassMetadata $class, $document)
    {
        foreach ($class->getEmbeddedAttributesMappings() as $mapping) {
            $value = $class->getPropertyMetadata($mapping->attributeName)->getValue($document);
            if ($value === null) {
                continue;
            }
            $values = $mapping->isOne() ? [$value] : $value;

            foreach ($values as $entry) {
                if ($this->uow->isScheduledForInsert($entry) || empty($this->uow->getDocumentChangeSet($entry))) {
                    continue;
                }
                $this->preUpdate($this->dm->getClassMetadata(get_class($entry)), $entry);
            }
        }
    }
391640
private function doRefresh($entity, array &$visited)
    {
        $oid = spl_object_id($entity);

        if (isset($visited[$oid])) {
            return; // Prevent infinite recursion
        }

        $visited[$oid] = $entity; // mark visited

        $class = $this->em->getClassMetadata(get_class($entity));

        if ($this->getEntityState($entity) !== self::STATE_MANAGED) {
            throw ORMInvalidArgumentException::entityNotManaged($entity);
        }

        $this->getEntityPersister($class->getClassName())->refresh(
            array_combine($class->getIdentifierFieldNames(), $this->entityIdentifiers[$oid]),
            $entity
        );

        $this->cascadeRefresh($entity, $visited);
    }
1113312
private function cascadePersist($entity, array &$visited)
    {
        $class = $this->em->getClassMetadata(get_class($entity));

        $associationMappings = array_filter(
            $class->associationMappings,
            function ($assoc) { return $assoc['isCascadePersist']; }
        );

        foreach ($associationMappings as $assoc) {
            $relatedEntities = $class->reflFields[$assoc['fieldName']]->getValue($entity);

            switch (true) {
                case ($relatedEntities instanceof PersistentCollection):
                    // Unwrap so that foreach() does not initialize
                    $relatedEntities = $relatedEntities->unwrap();
                    // break; is commented intentionally!

                case ($relatedEntities instanceof Collection):
                case (is_array($relatedEntities)):
                    if (($assoc['type'] & ClassMetadata::TO_MANY) <= 0) {
                        throw ORMInvalidArgumentException::invalidAssociation(
                            $this->em->getClassMetadata($assoc['targetEntity']),
                            $assoc,
                            $relatedEntities
                        );
                    }

                    foreach ($relatedEntities as $relatedEntity) {
                        $this->doPersist($relatedEntity, $visited);
                    }

                    break;

                case ($relatedEntities !== null):
                    if (! $relatedEntities instanceof $assoc['targetEntity']) {
                        throw ORMInvalidArgumentException::invalidAssociation(
                            $this->em->getClassMetadata($assoc['targetEntity']),
                            $assoc,
                            $relatedEntities
                        );
                    }

                    $this->doPersist($relatedEntities, $visited);
                    break;

                default:
                    // Do nothing
            }
        }
    }
200798
private function doRemove($object, array &$visited): void
    {
        $oid = spl_object_hash($object);
        if (isset($visited[$oid])) {
            return;
        }

        $visited[$oid] = true;

        // Cascade first to avoid problems with proxy initializing out of the identity map.
        $this->cascadeRemove($object, $visited);

        $class = $this->manager->getClassMetadata(get_class($object));
        $documentState = $this->getDocumentState($object);

        switch ($documentState) {
            case self::STATE_NEW:
            case self::STATE_REMOVED:
                // Nothing to do.
                break;

            case self::STATE_MANAGED:
                $this->lifecycleEventManager->preRemove($class, $object);
                $this->scheduleForDeletion($object);
                break;

            case self::STATE_DETACHED:
                throw new \InvalidArgumentException('Detached document cannot be removed');
            default:
                throw new \InvalidArgumentException('Unexpected document state '.$documentState);
        }
    }
849005
private function computeReferrerChanges($mapping, $referrer)
    {
        $targetClass = $this->dm->getClassMetadata(get_class($referrer));
        $state = $this->getDocumentState($referrer);

        switch ($state) {
            case self::STATE_NEW:
                if (!($mapping['cascade'] & ClassMetadata::CASCADE_PERSIST)) {
                    throw CascadeException::newDocumentFound(self::objToStr($referrer));
                }
                $this->persistNew($targetClass, $referrer);
                $this->computeChangeSet($targetClass, $referrer);
                break;
            case self::STATE_DETACHED:
                throw new InvalidArgumentException('A detached document was found through a referrer during cascading a persist operation: '.self::objToStr($referrer, $this->dm));
        }
    }