/** * @see \Doctrine\MongoDB\EagerCursor::current() * @see http://php.net/manual/en/iterator.current.php */ public function current() { $current = parent::current(); if ($current === null || !$this->hydrate) { return $current; } return $this->unitOfWork->getOrCreateDocument($this->class->name, $current, $this->unitOfWorkHints); }
function it_schedules_owning_document_for_update_when_setting_element_by_key_in_the_collection(MongoDBODMUnitOfWork $uow, DocumentStub $document, ObjectRepository $repository, ClassMetadata $classMetadata, EntityStub $entity4, EntityStub $entity8, EntityStub $entity15, EntityStub $newEntity) { $classMetadata->getIdentifier()->willReturn(['id']); $repository->findBy(['id' => [4, 8, 15]])->willReturn([$entity4, $entity8, $entity15]); $uow->getDocumentState($document)->willReturn(MongoDBODMUnitOfWork::STATE_MANAGED); $uow->isScheduledForUpdate($document)->willReturn(false); $uow->scheduleForUpdate($document)->shouldBeCalled(); $this->setOwner($document); $this->set(2, $newEntity); }
/** * @param PermissionsAwareInterface[] $documents * @param DocumentManager $dm * @param UnitOfWork $uow * @param bool $insert */ protected function process($documents, DocumentManager $dm, UnitOfWork $uow, $insert = false) { foreach ($documents as $document) { $perms = $document->getPermissions(); $files = $this->getFiles($document); foreach ($files as $file) { $filePermissions = $file->getPermissions()->clear()->inherit($perms); if ($insert) { $dm->persist($filePermissions); } $uow->computeChangeSet($dm->getClassMetadata(get_class($file)), $file); } } }
/** * Returns the reference representation to be stored in mongodb or null if not applicable. * * @param array $referenceMapping * @param Document $document * @return array|null */ public function prepareReferencedDocValue(array $referenceMapping, $document) { $id = null; if (is_array($document)) { $className = $referenceMapping['targetDocument']; } else { $className = get_class($document); $id = $this->uow->getDocumentIdentifier($document); } $class = $this->dm->getClassMetadata($className); if (null !== $id) { $id = $class->getDatabaseIdentifierValue($id); } $ref = array( $this->cmd . 'ref' => $class->getCollection(), $this->cmd . 'id' => $id, $this->cmd . 'db' => $class->getDatabase() ); // Store a discriminator value if the referenced document is not mapped explicitely to a targetDocument if ( ! isset($referenceMapping['targetDocument'])) { $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName(); $ref[$discriminatorField] = $discriminatorValue; } return $ref; }
private function loadReferenceManyCollection(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cmd = $this->cmd; $groupedIds = array(); foreach ($collection->getMongoData() as $reference) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $mongoId = $reference[$cmd . 'id']; $id = (string) $mongoId; $reference = $this->dm->getReference($className, $id); $collection->add($reference); if ($reference instanceof Proxy && !$reference->__isInitialized__) { if (!isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $mongoId; } } foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); $mongoCollection = $this->dm->getDocumentCollection($className); $data = $mongoCollection->find(array('_id' => array($cmd . 'in' => $ids))); foreach ($data as $documentData) { $document = $this->uow->getById((string) $documentData['_id'], $class->rootDocumentName); $data = $this->hydratorFactory->hydrate($document, $documentData); $this->uow->setOriginalDocumentData($document, $data); } } }
private function getAtomicCollectionUpdateQuery($document) { $update = array(); $collections = $this->uow->getScheduledCollections($document); $collPersister = $this->uow->getCollectionPersister(); foreach ($collections as $coll) { /* @var $coll PersistentCollection */ $mapping = $coll->getMapping(); if ($mapping['strategy'] !== "atomicSet" && $mapping['strategy'] !== "atomicSetArray") { continue; } if ($this->uow->isCollectionScheduledForUpdate($coll)) { $update = array_merge_recursive($update, $collPersister->prepareSetQuery($coll)); $this->uow->unscheduleCollectionUpdate($coll); /* TODO: * Collection can be set for both deletion and update if * PersistentCollection instance was changed. Since we're dealing * with collection update in one query we won't need the $unset. * Line can be removed once the issue is fixed. */ $this->uow->unscheduleCollectionDeletion($coll); } elseif ($this->uow->isCollectionScheduledForDeletion($coll)) { $update = array_merge_recursive($update, $collPersister->prepareDeleteQuery($coll)); $this->uow->unscheduleCollectionDeletion($coll); } } return $update; }
/** * Returns the value of the identifier field of a document * * Doctrine must know about this document, that is, the document must already * be persisted or added to the identity map before. Otherwise an * exception is thrown. * * @param object $document The document for which to get the identifier * @throws FormException If the document does not exist in Doctrine's * identity map */ public function getIdentifierValue($document) { if (!$this->unitOfWork->isInIdentityMap($document)) { throw new FormException('documents passed to the choice field must be managed'); } return $this->unitOfWork->getDocumentIdentifier($document); }
public function loadCollection(PersistentCollection $collection) { $mapping = $collection->getMapping(); $cmd = $this->dm->getConfiguration()->getMongoCmd(); $groupedIds = array(); foreach ($collection->getReferences() as $reference) { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $id = $reference[$cmd . 'id']; $reference = $this->dm->getReference($className, (string) $id); $collection->add($reference); if ($reference instanceof Proxy && ! $reference->__isInitialized__) { if ( ! isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $id; } } foreach ($groupedIds as $className => $ids) { $mongoCollection = $this->dm->getDocumentCollection($className); $data = $mongoCollection->find(array('_id' => array($cmd . 'in' => $ids))); $hints = array(Builder::HINT_REFRESH => true); foreach ($data as $id => $documentData) { $document = $this->uow->getOrCreateDocument($className, $documentData, $hints); } } }
/** * @param array $document * @return array|object|null */ private function hydrateDocument($document) { if ($document !== null && $this->class !== null) { return $this->unitOfWork->getOrCreateDocument($this->class->name, $document); } return $document; }
/** * @param PersistentCollection $collection * * @return Query */ public function createReferenceManyInverseSideQuery(PersistentCollection $collection) { $hints = $collection->getHints(); $mapping = $collection->getMapping(); $owner = $collection->getOwner(); $ownerClass = $this->dm->getClassMetadata(get_class($owner)); $targetClass = $this->dm->getClassMetadata($mapping['targetDocument']); $mappedByMapping = isset($targetClass->fieldMappings[$mapping['mappedBy']]) ? $targetClass->fieldMappings[$mapping['mappedBy']] : array(); $mappedByFieldName = isset($mappedByMapping['simple']) && $mappedByMapping['simple'] ? $mapping['mappedBy'] : $mapping['mappedBy'] . '.$id'; $criteria = $this->cm->merge(array($mappedByFieldName => $ownerClass->getIdentifierObject($owner)), $this->dm->getFilterCollection()->getFilterCriteria($targetClass), isset($mapping['criteria']) ? $mapping['criteria'] : array()); $criteria = $this->uow->getDocumentPersister($mapping['targetDocument'])->prepareQueryOrNewObj($criteria); $qb = $this->dm->createQueryBuilder($mapping['targetDocument'])->setQueryArray($criteria); if (isset($mapping['sort'])) { $qb->sort($mapping['sort']); } if (isset($mapping['limit'])) { $qb->limit($mapping['limit']); } if (isset($mapping['skip'])) { $qb->skip($mapping['skip']); } if (!empty($hints[Query::HINT_SLAVE_OKAY])) { $qb->slaveOkay(true); } if (!empty($hints[Query::HINT_READ_PREFERENCE])) { $qb->setReadPreference($hints[Query::HINT_READ_PREFERENCE], $hints[Query::HINT_READ_PREFERENCE_TAGS]); } return $qb->getQuery(); }
/** * Get shard key aware query for single document. * * @param object $document * * @return array */ private function getQueryForDocument($document) { $id = $this->uow->getDocumentIdentifier($document); $id = $this->class->getDatabaseIdentifierValue($id); $shardKeyQueryPart = $this->getShardKeyQuery($document); $query = array_merge(array('_id' => $id), $shardKeyQueryPart); return $query; }
private function loadReferenceManyCollectionOwningSide(PersistentCollection $collection) { $hints = $collection->getHints(); $mapping = $collection->getMapping(); $cmd = $this->cmd; $groupedIds = array(); foreach ($collection->getMongoData() as $key => $reference) { if (isset($mapping['simple']) && $mapping['simple']) { $className = $mapping['targetDocument']; $mongoId = $reference; } else { $className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference); $mongoId = $reference[$cmd . 'id']; } $id = (string) $mongoId; if (!$id) { continue; } $reference = $this->dm->getReference($className, $id); if ($mapping['strategy'] === 'set') { $collection->set($key, $reference); } else { $collection->add($reference); } if ($reference instanceof Proxy && !$reference->__isInitialized__) { if (!isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $mongoId; } } foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); $mongoCollection = $this->dm->getDocumentCollection($className); $criteria = array_merge(array('_id' => array($cmd . 'in' => $ids)), $this->dm->getFilterCollection()->getFilterCriteria($class), isset($mapping['criteria']) ? $mapping['criteria'] : array()); $cursor = $mongoCollection->find($criteria); if (isset($mapping['sort'])) { $cursor->sort($mapping['sort']); } if (isset($mapping['limit'])) { $cursor->limit($mapping['limit']); } if (isset($mapping['skip'])) { $cursor->skip($mapping['skip']); } if (isset($hints[Query::HINT_SLAVE_OKAY])) { $cursor->slaveOkay(true); } $documents = $cursor->toArray(); foreach ($documents as $documentData) { $document = $this->uow->getById((string) $documentData['_id'], $class->rootDocumentName); $data = $this->hydratorFactory->hydrate($document, $documentData); $this->uow->setOriginalDocumentData($document, $data); $document->__isInitialized__ = true; } } }
/** * Actual logic for setting an element in the collection. * * @param mixed $offset * @param mixed $value * @param bool $arrayAccess * @return bool */ private function doSet($offset, $value, $arrayAccess) { $arrayAccess ? $this->coll->offsetSet($offset, $value) : $this->coll->set($offset, $value); // Handle orphanRemoval if ($this->uow !== null && $this->isOrphanRemovalEnabled() && $value !== null) { $this->uow->unscheduleOrphanRemoval($value); } $this->changed(); }
/** * Returns the reference representation to be stored in mongodb or null if not applicable. * * @param ClassMetadata $class * @param Document $doc * @return array|null */ private function _prepareDocReference(ClassMetadata $class, $doc) { if (!is_object($doc)) { return $doc; } $id = $this->_uow->getDocumentIdentifier($doc); if (null !== $id) { $id = $class->getPHPIdentifierValue($id); } $ref = array($this->_cmd . 'ref' => $class->getCollection(), $this->_cmd . 'id' => $id, $this->_cmd . 'db' => $class->getDB()); return $ref; }
/** * @param object $embeddeDoc * @return bool */ private function isPartOfAtomicUpdate($embeddeDoc) { $isInDirtyCollection = false; while (null !== ($parentAssoc = $this->uow->getParentAssociation($embeddeDoc))) { list($mapping, $embeddeDoc, ) = $parentAssoc; if ($mapping['association'] === ClassMetadata::EMBED_MANY) { $classMetadata = $this->dm->getClassMetadata(get_class($embeddeDoc)); $parentColl = $classMetadata->getFieldValue($embeddeDoc, $mapping['fieldName']); $isInDirtyCollection |= $parentColl->isDirty(); } } return isset($mapping['association']) && $mapping['association'] === ClassMetadata::EMBED_MANY && ($mapping['strategy'] === 'atomicSet' || $mapping['strategy'] === 'atomicSetArray') && $isInDirtyCollection; }
/** * Returns the reference representation to be stored in mongodb or null if not applicable. * * @param array $referenceMapping * @param Document $document * @return array|null */ private function prepareReferencedDocValue(array $referenceMapping, $document) { $class = $this->dm->getClassMetadata(get_class($document)); $id = $this->uow->getDocumentIdentifier($document); if (null !== $id) { $id = $class->getDatabaseIdentifierValue($id); } $ref = array($this->cmd . 'ref' => $class->getCollection(), $this->cmd . 'id' => $id, $this->cmd . 'db' => $class->getDB()); if (!isset($referenceMapping['targetDocument'])) { $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName(); $ref[$discriminatorField] = $discriminatorValue; } return $ref; }
/** * 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; }
/** * Returns a DBRef array for the supplied document. * * @param mixed $document A document object * @param array $referenceMapping Mapping for the field that references the document * * @throws \InvalidArgumentException * @return array A DBRef array */ public function createDBRef($document, array $referenceMapping = null) { if (!is_object($document)) { throw new \InvalidArgumentException('Cannot create a DBRef, the document is not an object'); } $class = $this->getClassMetadata(get_class($document)); $id = $this->unitOfWork->getDocumentIdentifier($document); if (!$id) { throw new \RuntimeException(sprintf('Cannot create a DBRef for class %s without an identifier. Have you forgotten to persist/merge the document first?', $class->name)); } if ($referenceMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_ID) { if ($class->inheritanceType === ClassMetadataInfo::INHERITANCE_TYPE_SINGLE_COLLECTION) { throw MappingException::simpleReferenceMustNotTargetDiscriminatedDocument($referenceMapping['targetDocument']); } return $class->getDatabaseIdentifierValue($id); } $dbRef = array('$ref' => $class->getCollection(), '$id' => $class->getDatabaseIdentifierValue($id)); if ($referenceMapping['storeAs'] === ClassMetadataInfo::REFERENCE_STORE_AS_DB_REF_WITH_DB) { $dbRef['$db'] = $this->getDocumentDatabase($class->name)->getName(); } /* If the class has a discriminator (field and value), use it. A child * class that is not defined in the discriminator map may only have a * discriminator field and no value, so default to the full class name. */ if (isset($class->discriminatorField)) { $dbRef[$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name; } /* Add a discriminator value if the referenced document is not mapped * explicitly to a targetDocument class. */ if ($referenceMapping !== null && !isset($referenceMapping['targetDocument'])) { $discriminatorField = $referenceMapping['discriminatorField']; $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->name, $referenceMapping['discriminatorMap']) : $class->name; /* If the discriminator value was not found in the map, use the full * class name. In the future, it may be preferable to throw an * exception here (perhaps based on some strictness option). * * @see PersistenceBuilder::prepareEmbeddedDocumentValue() */ if ($discriminatorValue === false) { $discriminatorValue = $class->name; } $dbRef[$discriminatorField] = $discriminatorValue; } return $dbRef; }
/** * {@inheritdoc} */ public function clear() { if ($this->initialized && $this->isEmpty()) { return; } if ($this->isOrphanRemovalEnabled()) { foreach ($this->coll as $element) { $this->uow->scheduleOrphanRemoval($element); } } $this->mongoData = array(); $this->coll->clear(); if ($this->mapping['isOwningSide']) { $this->changed(); $this->uow->scheduleCollectionDeletion($this); $this->takeSnapshot(); } }
private function handleCollections($document, $options) { // Collection deletions (deletions of complete collections) foreach ($this->uow->getScheduledCollections($document) as $coll) { if ($this->uow->isCollectionScheduledForDeletion($coll)) { $this->cp->delete($coll, $options); } } // Collection updates (deleteRows, updateRows, insertRows) foreach ($this->uow->getScheduledCollections($document) as $coll) { if ($this->uow->isCollectionScheduledForUpdate($coll)) { $this->cp->update($coll, $options); } } // Take new snapshots from visited collections foreach ($this->uow->getVisitedCollections($document) as $coll) { $coll->takeSnapshot(); } }
/** * Returns a DBRef array for the supplied document. * * @param mixed $document A document object * @param array $referenceMapping Mapping for the field that references the document * * @throws \InvalidArgumentException * @return array A DBRef array */ public function createDBRef($document, array $referenceMapping = null) { if (!is_object($document)) { throw new \InvalidArgumentException('Cannot create a DBRef, the document is not an object'); } $class = $this->getClassMetadata(get_class($document)); $id = $this->unitOfWork->getDocumentIdentifier($document); if (!$id) { throw new \RuntimeException(sprintf('Cannot create a DBRef without an identifier. UnitOfWork::getDocumentIdentifier() did not return an identifier for class %s', $class->name)); } if (!empty($referenceMapping['simple'])) { return $class->getDatabaseIdentifierValue($id); } $dbRef = array('$ref' => $class->getCollection(), '$id' => $class->getDatabaseIdentifierValue($id)); if (empty($referenceMapping['partial'])) { $dbRef['$db'] = $this->getDocumentDatabase($class->name)->getName(); } /* If the class has a discriminator (field and value), use it. A child * class that is not defined in the discriminator map may only have a * discriminator field and no value, so default to the full class name. */ if (isset($class->discriminatorField)) { $dbRef[$class->discriminatorField] = isset($class->discriminatorValue) ? $class->discriminatorValue : $class->name; } /* Add a discriminator value if the referenced document is not mapped * explicitly to a targetDocument class. */ if ($referenceMapping !== null && !isset($referenceMapping['targetDocument'])) { $discriminatorField = $referenceMapping['discriminatorField']; $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->name, $referenceMapping['discriminatorMap']) : $class->name; /* If the discriminator value was not found in the map, use the full * class name. In the future, it may be preferable to throw an * exception here (perhaps based on some strictness option). * * @see PersistenceBuilder::prepareEmbeddedDocumentValue() */ if ($discriminatorValue === false) { $discriminatorValue = $class->name; } $dbRef[$discriminatorField] = $discriminatorValue; } return $dbRef; }
/** * Returns a DBRef array for the supplied document. * * @param mixed $document A document object * @param array $referenceMapping Mapping for the field the references the document * * @return array A DBRef array */ public function createDBRef($document, array $referenceMapping = null) { if (!is_object($document)) { throw new \InvalidArgumentException('Cannot create a DBRef, the document is not an object'); } $className = get_class($document); $class = $this->getClassMetadata($className); $id = $this->unitOfWork->getDocumentIdentifier($document); $dbRef = array($this->cmd . 'ref' => $class->getCollection(), $this->cmd . 'id' => $class->getDatabaseIdentifierValue($id), $this->cmd . 'db' => $this->getDocumentDatabase($className)->getName()); if ($class->discriminatorField) { $dbRef[$class->discriminatorField['name']] = $class->discriminatorValue; } // add a discriminator value if the referenced document is not mapped explicitely to a targetDocument if ($referenceMapping && !isset($referenceMapping['targetDocument'])) { $discriminatorField = isset($referenceMapping['discriminatorField']) ? $referenceMapping['discriminatorField'] : '_doctrine_class_name'; $discriminatorValue = isset($referenceMapping['discriminatorMap']) ? array_search($class->getName(), $referenceMapping['discriminatorMap']) : $class->getName(); $dbRef[$discriminatorField] = $discriminatorValue; } return $dbRef; }
/** * Cascades the postUpdate and postPersist events to embedded documents. * * @param ClassMetadata $class * @param object $document */ private function cascadePostUpdate(ClassMetadata $class, $document) { foreach ($class->getEmbeddedFieldsMappings() as $mapping) { $value = $class->reflFields[$mapping['fieldName']]->getValue($document); if ($value === null) { continue; } $values = $mapping['type'] === ClassMetadata::ONE ? array($value) : $value; foreach ($values as $entry) { if (empty($this->uow->getDocumentChangeSet($entry)) && !$this->uow->hasScheduledCollections($entry)) { continue; } $entryClass = $this->dm->getClassMetadata(get_class($entry)); $event = $this->uow->isScheduledForInsert($entry) ? Events::postPersist : Events::postUpdate; $entryClass->invokeLifecycleCallbacks($event, $entry, array(new LifecycleEventArgs($entry, $this->dm))); $this->evm->dispatchEvent($event, new LifecycleEventArgs($entry, $this->dm)); $this->cascadePostUpdate($entryClass, $entry); } } }
/** * Adds identifiers from a PersistentCollection to $groupedIds. * * If the relation contains simple references, the mapping is assumed to * have a target document class defined. Without that, there is no way to * infer the class of the referenced documents. * * @param PersistentCollection $persistentCollection * @param array $groupedIds */ private function addManyReferences(PersistentCollection $persistentCollection, array &$groupedIds) { $mapping = $persistentCollection->getMapping(); if (!empty($mapping['simple'])) { $className = $mapping['targetDocument']; $class = $this->dm->getClassMetadata($className); } foreach ($persistentCollection->getMongoData() as $reference) { if (!empty($mapping['simple'])) { $id = $reference; } else { $id = $reference['$id']; $className = $this->uow->getClassNameForAssociation($mapping, $reference); $class = $this->dm->getClassMetadata($className); } $document = $this->uow->tryGetById($id, $class); if (!$document || $document instanceof Proxy && !$document->__isInitialized()) { $id = $class->getPHPIdentifierValue($id); $groupedIds[$className][serialize($id)] = $id; } } }
/** * @param PersistentCollection $collection * @param array $groupedIds * * @throws \Doctrine\ODM\MongoDB\MongoDBException */ private function loadActualDataForSortedReferenceManyCollectionByIds(PersistentCollection $collection, array $groupedIds) { $mapping = $collection->getMapping(); $hints = $collection->getHints(); foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); $mongoCollection = $this->dm->getDocumentCollection($className); $criteria = $this->cm->merge(array('_id' => array('$in' => array_values($ids))), $this->dm->getFilterCollection()->getFilterCriteria($class), isset($mapping['criteria']) ? $mapping['criteria'] : array()); $criteria = $this->uow->getDocumentPersister($className)->prepareQueryOrNewObj($criteria); $cursor = $mongoCollection->find($criteria); if (isset($mapping['sort'])) { $cursor->sort($mapping['sort']); } if (isset($mapping['limit'])) { $cursor->limit($mapping['limit']); } if (isset($mapping['skip'])) { $cursor->skip($mapping['skip']); } if (!empty($hints[Query::HINT_SLAVE_OKAY])) { $cursor->slaveOkay(true); } if (!empty($hints[Query::HINT_READ_PREFERENCE])) { $cursor->setReadPreference($hints[Query::HINT_READ_PREFERENCE], $hints[Query::HINT_READ_PREFERENCE_TAGS]); } $documents = $cursor->toArray(false); foreach ($documents as $documentData) { $docId = $documentData['_id']; $document = $this->uow->getById($docId, $class); $data = $this->hydratorFactory->hydrate($document, $documentData); $this->uow->setOriginalDocumentData($document, $data); $document->__isInitialized__ = true; $collection->add($document); } } }
/** * {@inheritdoc} */ public function clear() { if ($this->initialized && $this->isEmpty()) { return; } if ($this->isOrphanRemovalEnabled()) { foreach ($this->coll as $element) { $this->uow->scheduleOrphanRemoval($element); } } $this->mongoData = array(); $this->coll->clear(); // Nothing to do for inverse-side collections if (!$this->mapping['isOwningSide']) { return; } // Nothing to do if the collection was initialized but contained no data if ($this->initialized && empty($this->snapshot)) { return; } $this->changed(); $this->uow->scheduleCollectionDeletion($this); $this->takeSnapshot(); }
/** * Finds a single document by a set of criteria. * * @param array $criteria * @return object */ public function findOneBy(array $criteria) { return $this->uow->getDocumentPersister($this->documentName)->load($criteria); }
private function isScheduledForInsert($document) { return $this->uow->isScheduledForInsert($document) || $this->uow->getDocumentPersister(get_class($document))->isQueuedForInsert($document); }
protected function getDocumentPersister() { return $this->uow->getDocumentPersister($this->documentName); }
private function getAtomicCollectionUpdateQuery($document) { $update = array(); $atomicCollUpdates = array(); $atomicCollDeletes = array(); $collPersister = $this->uow->getCollectionPersister(); /* Collect all atomic collections (top-level and nested) to be included * in the update. */ foreach ($this->uow->getScheduledCollections($document) as $coll) { /* If this is a top-level, atomic collection, its scheduled update * or deletion must be included in the document's update query. */ if ($coll->getOwner() === $document) { $mapping = $coll->getMapping(); if ($mapping['strategy'] !== "atomicSet" && $mapping['strategy'] !== "atomicSetArray") { continue; } if ($this->uow->isCollectionScheduledForUpdate($coll)) { $atomicCollUpdates[spl_object_hash($coll)] = $coll; } elseif ($this->uow->isCollectionScheduledForDeletion($coll)) { $atomicCollDeletes[spl_object_hash($coll)] = $coll; } continue; } /* Otherwise, the collection is nested. Check if its top-most parent * is an atomic collection and include it for updating if so. This * is necessary because the atomic parent may not have directly * changed. */ $parent = $coll->getOwner(); while (null !== ($parentAssoc = $this->uow->getParentAssociation($parent))) { list($mapping, $parent, ) = $parentAssoc; } if (!isset($mapping['association']) || $mapping['association'] !== ClassMetadata::EMBED_MANY || $mapping['strategy'] !== 'atomicSet' && $mapping['strategy'] !== 'atomicSetArray') { continue; } $classMetadata = $this->dm->getClassMetadata(get_class($document)); $parentColl = $classMetadata->getFieldValue($document, $mapping['fieldName']); /* It's possible that the atomic parent was independently scheduled * for deletion. In that case, updating nested data is unnecessary. */ if (!$this->uow->isCollectionScheduledForDeletion($parentColl)) { $atomicCollUpdates[spl_object_hash($parentColl)] = $parentColl; } } foreach ($atomicCollUpdates as $coll) { $update = array_merge_recursive($update, $collPersister->prepareSetQuery($coll)); /* Note: If the collection is only be handled because it's an atomic * parent of a scheduled child, the following calls are NOPs. */ $this->uow->unscheduleCollectionUpdate($coll); } foreach ($atomicCollDeletes as $coll) { $update = array_merge_recursive($update, $collPersister->prepareDeleteQuery($coll)); /* Note: We don't need to call unscheduleCollectionUpdate(), because * the collection should never have been added to $atomicCollDeletes * if it was independently scheduled for update. */ $this->uow->unscheduleCollectionDeletion($coll); } return $update; }