/** * prepares array of values to be stored in mongo * to represent embedded object * @param ClassMetadata $class * @param Document $doc * @return array */ private function _prepareDocEmbeded($class, $doc) { $changeset = array(); if (is_array($doc) || $doc instanceof Collection) { foreach ($doc as $val) { $changeset[] = $this->_prepareDocEmbeded($class, $val); } } else { foreach ($class->fieldMappings as $mapping) { $rawValue = $class->getFieldValue($doc, $mapping['fieldName']); if (!isset($rawValue)) { continue; } if (isset($mapping['embedded']) || isset($mapping['reference'])) { $classMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); if (isset($mapping['embedded'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $doc) { $value[] = $this->_prepareDocEmbeded($classMetadata, $doc); } } elseif ($mapping['type'] == 'one') { $value = $this->_prepareDocEmbeded($classMetadata, $rawValue); } } elseif (isset($mapping['reference'])) { if ($mapping['type'] == 'many') { $value = array(); foreach ($rawValue as $doc) { $value[] = $this->_prepareDocReference($classMetadata, $doc); } } else { $value = $this->_prepareDocReference($classMetadata, $rawValue); } } } else { $value = Types::getType($mapping['type'])->convertToDatabaseValue($rawValue); } $changeset[$mapping['fieldName']] = $value; } } return $changeset; }
/** * Hydrate array of MongoDB document data into the given document object * based on the mapping information provided in the ClassMetadata instance. * * @param ClassMetadata $metadata The ClassMetadata instance for mapping information. * @param string $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(ClassMetadata $metadata, $document, $data) { $values = array(); foreach ($metadata->fieldMappings as $mapping) { if (!isset($data[$mapping['fieldName']])) { continue; } if (isset($mapping['embedded'])) { $embeddedMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); $embeddedDocument = $embeddedMetadata->newInstance(); if ($mapping['type'] === 'many') { $documents = new ArrayCollection(); foreach ($data[$mapping['fieldName']] as $docArray) { $doc = clone $embeddedDocument; $this->hydrate($embeddedMetadata, $doc, $docArray); $documents->add($doc); } $metadata->setFieldValue($document, $mapping['fieldName'], $documents); $value = $documents; } else { $value = clone $embeddedDocument; $this->hydrate($embeddedMetadata, $value, $data[$mapping['fieldName']]); $metadata->setFieldValue($document, $mapping['fieldName'], $value); } } elseif (isset($mapping['reference'])) { $targetMetadata = $this->_dm->getClassMetadata($mapping['targetDocument']); $targetDocument = $targetMetadata->newInstance(); $value = isset($data[$mapping['fieldName']]) ? $data[$mapping['fieldName']] : null; if ($mapping['type'] === 'one' && isset($value['$id'])) { $id = (string) $value['$id']; $proxy = $this->_dm->getReference($mapping['targetDocument'], $id); $metadata->setFieldValue($document, $mapping['fieldName'], $proxy); } elseif ($mapping['type'] === 'many' && (is_array($value) || $value instanceof Collection)) { $documents = new PersistentCollection($this->_dm, $targetMetadata, new ArrayCollection()); $documents->setInitialized(false); foreach ($value as $v) { $id = (string) $v['$id']; $proxy = $this->_dm->getReference($mapping['targetDocument'], $id); $documents->add($proxy); } $metadata->setFieldValue($document, $mapping['fieldName'], $documents); } } else { $value = $data[$mapping['fieldName']]; $value = Types::getType($mapping['type'])->convertToPHPValue($value); $metadata->setFieldValue($document, $mapping['fieldName'], $value); } if (isset($value)) { $values[$mapping['fieldName']] = $value; } } if (isset($data['_id'])) { $metadata->setIdentifierValue($document, (string) $data['_id']); } return $values; }