/**
* Hydrate array of MongoDB document data into the given document object.
*
* @param object $document The document object to hydrate the data into.
* @param array $data The array of document data.
* @return array $values The array of hydrated values.
*/
public function hydrate($document, &$data)
{
$metadata = $this->dm->getClassMetadata(get_class($document));
if (isset($metadata->alsoLoadMethods)) {
foreach ($metadata->alsoLoadMethods as $fieldName => $method) {
if (isset($data[$fieldName])) {
$document->{$method}($data[$fieldName]);
}
}
}
foreach ($metadata->fieldMappings as $mapping) {
if (isset($mapping['alsoLoadFields'])) {
$rawValue = null;
$names = isset($mapping['alsoLoadFields']) ? $mapping['alsoLoadFields'] : array();
array_unshift($names, $mapping['name']);
foreach ($names as $name) {
if (isset($data[$name])) {
$rawValue = $data[$name];
break;
}
}
} else {
$rawValue = isset($data[$mapping['name']]) ? $data[$mapping['name']] : null;
}
if ($rawValue === null) {
continue;
}
$value = null;
// Hydrate embedded
if (isset($mapping['embedded'])) {
if ($mapping['type'] === 'one') {
$embeddedDocument = $rawValue;
$className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument);
$embeddedMetadata = $this->dm->getClassMetadata($className);
$value = $embeddedMetadata->newInstance();
$this->hydrate($value, $embeddedDocument);
$this->dm->getUnitOfWork()->registerManagedEmbeddedDocument($value, $embeddedDocument);
} elseif ($mapping['type'] === 'many') {
$embeddedDocuments = $rawValue;
$coll = new PersistentCollection(new ArrayCollection());
foreach ($embeddedDocuments as $embeddedDocument) {
$className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $embeddedDocument);
$embeddedMetadata = $this->dm->getClassMetadata($className);
$embeddedDocumentObject = $embeddedMetadata->newInstance();
$this->hydrate($embeddedDocumentObject, $embeddedDocument);
$this->dm->getUnitOfWork()->registerManagedEmbeddedDocument($embeddedDocumentObject, $embeddedDocument);
$coll->add($embeddedDocumentObject);
}
$coll->setOwner($document, $mapping);
$coll->takeSnapshot();
$value = $coll;
}
// Hydrate reference
} elseif (isset($mapping['reference'])) {
$reference = $rawValue;
if ($mapping['type'] === 'one' && isset($reference[$this->cmd . 'id'])) {
$className = $this->dm->getClassNameFromDiscriminatorValue($mapping, $reference);
$targetMetadata = $this->dm->getClassMetadata($className);
$id = $targetMetadata->getPHPIdentifierValue($reference[$this->cmd . 'id']);
$value = $this->dm->getReference($className, $id);
} elseif ($mapping['type'] === 'many' && (is_array($reference) || $reference instanceof Collection)) {
$references = $reference;
$value = new PersistentCollection(new ArrayCollection(), $this->dm);
$value->setInitialized(false);
$value->setOwner($document, $mapping);
// Delay any hydration of reference objects until the collection is
// accessed and initialized for the first ime
$value->setReferences($references);
}
// Hydrate regular field
} else {
$value = Type::getType($mapping['type'])->convertToPHPValue($rawValue);
}
// Set hydrated field value to document
if ($value !== null) {
$data[$mapping['name']] = $value;
$metadata->setFieldValue($document, $mapping['fieldName'], $value);
}
}
// Set the document identifier
if (isset($data['_id'])) {
$metadata->setIdentifierValue($document, $data['_id']);
$data[$metadata->identifier] = $data['_id'];
unset($data['_id']);
}
return $document;
}