/** * Cascades the save operation to associated documents. * * @param object $document * @param array $visited */ private function cascadePersist($document, array &$visited) { $class = $this->dm->getClassMetadata(get_class($document)); $associationMappings = array_filter($class->associationMappings, function ($assoc) { return $assoc['isCascadePersist']; }); foreach ($associationMappings as $fieldName => $mapping) { $relatedDocuments = $class->reflFields[$fieldName]->getValue($document); if ($relatedDocuments instanceof Collection || is_array($relatedDocuments)) { if ($relatedDocuments instanceof PersistentCollection) { if ($relatedDocuments->getOwner() !== $document) { $relatedDocuments = $this->fixPersistentCollectionOwnership($relatedDocuments, $document, $class, $mapping['fieldName']); } // Unwrap so that foreach() does not initialize $relatedDocuments = $relatedDocuments->unwrap(); } $count = 0; foreach ($relatedDocuments as $relatedKey => $relatedDocument) { if (!empty($mapping['embedded'])) { list(, $knownParent, ) = $this->getParentAssociation($relatedDocument); if ($knownParent && $knownParent !== $document) { $relatedDocument = clone $relatedDocument; $relatedDocuments[$relatedKey] = $relatedDocument; } $pathKey = !isset($mapping['strategy']) || CollectionHelper::isList($mapping['strategy']) ? $count++ : $relatedKey; $this->setParentAssociation($relatedDocument, $mapping, $document, $mapping['fieldName'] . '.' . $pathKey); } $this->doPersist($relatedDocument, $visited); } } elseif ($relatedDocuments !== null) { if (!empty($mapping['embedded'])) { list(, $knownParent, ) = $this->getParentAssociation($relatedDocuments); if ($knownParent && $knownParent !== $document) { $relatedDocuments = clone $relatedDocuments; $class->setFieldValue($document, $mapping['fieldName'], $relatedDocuments); } $this->setParentAssociation($relatedDocuments, $mapping, $document, $mapping['fieldName']); } $this->doPersist($relatedDocuments, $visited); } } }
/** * INTERNAL: * Tells this collection to take a snapshot of its current state reindexing * itself numerically if using save strategy that is enforcing BSON array. * Reindexing is safe as snapshot is taken only after synchronizing collection * with database or clearing it. */ public function takeSnapshot() { if (CollectionHelper::isList($this->mapping['strategy'])) { $array = $this->coll->toArray(); $this->coll->clear(); foreach ($array as $document) { $this->coll->add($document); } } $this->snapshot = $this->coll->toArray(); $this->isDirty = false; }
/** * Returns the collection representation to be stored and unschedules it afterwards. * * @param PersistentCollection $coll * @param bool $includeNestedCollections * @return array */ public function prepareAssociatedCollectionValue(PersistentCollection $coll, $includeNestedCollections = false) { $mapping = $coll->getMapping(); $pb = $this; $callback = isset($mapping['embedded']) ? function ($v) use($pb, $mapping, $includeNestedCollections) { return $pb->prepareEmbeddedDocumentValue($mapping, $v, $includeNestedCollections); } : function ($v) use($pb, $mapping) { return $pb->prepareReferencedDocumentValue($mapping, $v); }; $setData = $coll->map($callback)->toArray(); if (CollectionHelper::isList($mapping['strategy'])) { $setData = array_values($setData); } $this->uow->unscheduleCollectionDeletion($coll); $this->uow->unscheduleCollectionUpdate($coll); return $setData; }