public function getOrCreateDocument($className, $data, &$hints = array(), $document = null)
{
$class = $this->dm->getClassMetadata($className);
// @TODO figure out how to remove this
$discriminatorValue = null;
if (isset($class->discriminatorField, $data[$class->discriminatorField])) {
$discriminatorValue = $data[$class->discriminatorField];
} elseif (isset($class->defaultDiscriminatorValue)) {
$discriminatorValue = $class->defaultDiscriminatorValue;
}
if ($discriminatorValue !== null) {
$className = isset($class->discriminatorMap[$discriminatorValue]) ? $class->discriminatorMap[$discriminatorValue] : $discriminatorValue;
$class = $this->dm->getClassMetadata($className);
unset($data[$class->discriminatorField]);
}
if (!empty($hints[Query::HINT_READ_ONLY])) {
$document = $class->newInstance();
$this->hydratorFactory->hydrate($document, $data, $hints);
return $document;
}
$isManagedObject = false;
if (!$class->isQueryResultDocument) {
$id = $class->getDatabaseIdentifierValue($data['_id']);
$serializedId = serialize($id);
$isManagedObject = isset($this->identityMap[$class->name][$serializedId]);
}
if ($isManagedObject) {
$document = $this->identityMap[$class->name][$serializedId];
$oid = spl_object_hash($document);
if ($document instanceof Proxy && !$document->__isInitialized__) {
$document->__isInitialized__ = true;
$overrideLocalValues = true;
if ($document instanceof NotifyPropertyChanged) {
$document->addPropertyChangedListener($this);
}
} else {
$overrideLocalValues = !empty($hints[Query::HINT_REFRESH]);
}
if ($overrideLocalValues) {
$data = $this->hydratorFactory->hydrate($document, $data, $hints);
$this->originalDocumentData[$oid] = $data;
}
} else {
if ($document === null) {
$document = $class->newInstance();
}
if (!$class->isQueryResultDocument) {
$this->registerManaged($document, $id, $data);
$oid = spl_object_hash($document);
$this->documentStates[$oid] = self::STATE_MANAGED;
$this->identityMap[$class->name][$serializedId] = $document;
}
$data = $this->hydratorFactory->hydrate($document, $data, $hints);
if (!$class->isQueryResultDocument) {
$this->originalDocumentData[$oid] = $data;
}
}
return $document;
}