/** * Gets a partial reference to the document identified by the given type and identifier * without actually loading it, if the document is not yet loaded. * * The returned reference may be a partial object if the document is not yet loaded/managed. * If it is a partial object it will not initialize the rest of the document state on access. * Thus you can only ever safely access the identifier of a document obtained through * this method. * * The use-cases for partial references involve maintaining bidirectional associations * without loading one side of the association or to update a document without loading it. * Note, however, that in the latter case the original (persistent) document data will * never be visible to the application (especially not event listeners) as it will * never be loaded in the first place. * * @param string $documentName The name of the document type. * @param mixed $identifier The document identifier. * @return object The (partial) document reference. */ public function getPartialReference($documentName, $identifier) { $class = $this->metadataFactory->getMetadataFor(ltrim($documentName, '\\')); // Check identity map first, if its already in there just return it. if ($document = $this->unitOfWork->tryGetById($identifier, $class)) { return $document; } $document = $class->newInstance(); $class->setIdentifierValue($document, $identifier); $this->unitOfWork->registerManaged($document, $identifier, array()); return $document; }
/** * 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; } } }
/** * Finds a document by its identifier * * @param string|object $id The identifier * @param int $lockMode * @param int $lockVersion * @throws Mapping\MappingException * @throws LockException * @return object The document. */ public function find($id, $lockMode = LockMode::NONE, $lockVersion = null) { if ($id === null) { return; } /* TODO: What if the ID object has a field with the same name as the * class' mapped identifier field name? */ if (is_array($id)) { list($identifierFieldName) = $this->class->getIdentifierFieldNames(); if (isset($id[$identifierFieldName])) { $id = $id[$identifierFieldName]; } } // Check identity map first if ($document = $this->uow->tryGetById($id, $this->class)) { if ($lockMode != LockMode::NONE) { $this->dm->lock($document, $lockMode, $lockVersion); } return $document; // Hit! } $criteria = array('_id' => $id); if ($lockMode == LockMode::NONE) { return $this->getDocumentPersister()->load($criteria); } if ($lockMode == LockMode::OPTIMISTIC) { if (!$this->class->isVersioned) { throw LockException::notVersioned($this->documentName); } if ($document = $this->getDocumentPersister()->load($criteria)) { $this->uow->lock($document, $lockMode, $lockVersion); } return $document; } return $this->getDocumentPersister()->load($criteria, null, array(), $lockMode); }