Gets the identifier of a document.
public getDocumentIdentifier ( object $document ) : mixed | ||
$document | object | |
return | mixed | The identifier value |
/** * Releases any lock that exists on this document. * * @param object $document */ public function unlock($document) { $criteria = array('_id' => $this->uow->getDocumentIdentifier($document)); $lockMapping = $this->class->fieldMappings[$this->class->lockField]; $this->collection->update($criteria, array($this->cmd.'unset' => array($lockMapping['name'] => true))); $this->class->reflFields[$this->class->lockField]->setValue($document, null); }
/** * 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); }
/** * 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; }
/** * 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; }
/** * Prime a collection of documents property with an efficient single query instead of * lazily loading each field with a single query. * * @param Iterator $collection * @param string $fieldName * @param Closure|boolean $primer * @param array $hints */ public function primeCollection(Iterator $collection, $fieldName, $primer, array $hints = array()) { $collection = $collection->toArray(); if (!count($collection)) { return; } $collectionMetaData = $this->dm->getClassMetaData(get_class(current($collection))); $fieldMapping = $collectionMetaData->fieldMappings[$fieldName]; $cmd = $this->cmd; $groupedIds = array(); foreach ($collection as $element) { if ($fieldMapping['type'] == 'many') { $fieldValue = $collectionMetaData->getFieldValue($element, $fieldName); if ($fieldValue instanceof PersistentCollection) { foreach ($fieldValue->getMongoData() as $key => $reference) { if (isset($fieldMapping['simple']) && $fieldMapping['simple']) { $className = $fieldMapping['targetDocument']; $mongoId = $reference; } else { $className = $this->dm->getClassNameFromDiscriminatorValue($fieldMapping, $reference); $mongoId = $reference[$cmd . 'id']; } $id = (string) $mongoId; $document = $this->uow->tryGetById($id, $className); if (!$document || $document instanceof Proxy && !$document->__isInitialized__) { if (!isset($groupedIds[$className])) { $groupedIds[$className] = array(); } $groupedIds[$className][] = $mongoId; } } } } else { if ($fieldMapping['type'] == 'one') { $document = $collectionMetaData->getFieldValue($element, $fieldName); if ($document && $document instanceof Proxy && !$document->__isInitialized__) { $class = $this->dm->getClassMetadata(get_class($document)); $groupedIds[$class->name][] = $this->uow->getDocumentIdentifier($document); } } } } foreach ($groupedIds as $className => $ids) { $class = $this->dm->getClassMetadata($className); if ($primer instanceof \Closure) { $primer($this->dm, $className, $fieldName, $ids, $hints); } else { $repository = $this->dm->getRepository($className); $qb = $repository->createQueryBuilder()->field($class->identifier)->in($ids); if (isset($hints[Query::HINT_SLAVE_OKAY])) { $qb->slaveOkay(true); } $query = $qb->getQuery(); $query->execute()->toArray(); } } }
/** * 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; }
/** * 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; }
/** * Prime references within a mapped field of one or more documents. * * If a $primer callable is provided, it should have the same signature as * the default primer defined in the constructor. If $primer is not * callable, the default primer will be used. * * @param ClassMetadata $class Class metadata for the document * @param array|\Traversable $documents Documents containing references to prime * @param string $fieldName Field name containing references to prime * @param array $hints UnitOfWork hints for priming queries * @param callable $primer Optional primer callable * @throws \InvalidArgumentException If the mapped field is not the owning * side of a reference relationship. * @throws \InvalidArgumentException If $primer is not callable * @throws \LogicException If the mapped field is a simple reference and is * missing a target document class. */ public function primeReferences(ClassMetadata $class, $documents, $fieldName, array $hints = array(), $primer = null) { $data = $this->parseDotSyntaxForPrimer($fieldName, $class, $documents); $mapping = $data['mapping']; $fieldName = $data['fieldName']; $class = $data['class']; $documents = $data['documents']; /* Inverse-side references would need to be populated before we can * collect references to be primed. This is not supported. */ if (!isset($mapping['reference']) || !$mapping['isOwningSide']) { throw new \InvalidArgumentException(sprintf('Field "%s" is not the owning side of a reference relationship in class "%s"', $fieldName, $class->name)); } /* Simple reference require a target document class so we can construct * the priming query. */ if (!empty($mapping['simple']) && empty($mapping['targetDocument'])) { throw new \LogicException(sprintf('Field "%s" is a simple reference without a target document class in class "%s"', $fieldName, $class->name)); } if ($primer !== null && !is_callable($primer)) { throw new \InvalidArgumentException('$primer is not callable'); } $primer = $primer ?: $this->defaultPrimer; $groupedIds = array(); /* @var $document PersistentCollection */ foreach ($documents as $document) { $fieldValue = $class->getFieldValue($document, $fieldName); /* The field will need to be either a Proxy (reference-one) or * PersistentCollection (reference-many) in order to prime anything. */ if (!is_object($fieldValue)) { continue; } if ($mapping['type'] === 'one' && $fieldValue instanceof Proxy && !$fieldValue->__isInitialized()) { $refClass = $this->dm->getClassMetadata(get_class($fieldValue)); $id = $this->uow->getDocumentIdentifier($fieldValue); $groupedIds[$refClass->name][serialize($id)] = $id; } elseif ($mapping['type'] == 'many' && $fieldValue instanceof PersistentCollection) { $this->addManyReferences($fieldValue, $groupedIds); } } foreach ($groupedIds as $className => $ids) { $refClass = $this->dm->getClassMetadata($className); call_user_func($primer, $this->dm, $refClass, array_values($ids), $hints); } }
/** * 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; }
/** * 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; }