/** * @inheritdoc */ function hydrate($document, $data, array $hints = []) { $hydratedData = []; foreach ($this->metadata->fieldMappings as $fieldName => $mapping) { $name = $mapping['name']; $propertyValue = isset($data[$name]) ? $data[$name] : null; if (!isset($mapping['association'])) { if ($propertyValue === null) { continue; } $type = Type::getType($mapping['type']); $value = $type->convertToPHPValue($propertyValue); $this->metadata->reflFields[$fieldName]->setValue($document, $value); $hydratedData[$fieldName] = $value; continue; } if ($mapping['association'] & ClassMetadata::TO_MANY) { $coll = new PersistentCollection(new ArrayCollection(), $this->dm, $this->uow); $coll->setOwner($document, $mapping); $coll->setInitialized(false); if ($propertyValue) { $coll->setData($propertyValue); } $this->metadata->reflFields[$fieldName]->setValue($document, $coll); $hydratedData[$fieldName] = $coll; continue; } if ($propertyValue === null) { continue; } if ($mapping['association'] === ClassMetadata::LINK) { if (is_string($propertyValue)) { $link = $this->dm->getReference($propertyValue); } else { $link = $this->uow->getOrCreateDocument($propertyValue); } $this->metadata->reflFields[$fieldName]->setValue($document, $link); $hydratedData[$fieldName] = $link; continue; } if ($mapping['association'] === ClassMetadata::EMBED) { // an embed one must have @class, we would support generic JSON properties via another mapping type if (!isset($propertyValue[self::ORIENT_PROPERTY_CLASS])) { throw new HydratorException(sprintf("missing @class for embedded property '%s'", $name)); } $oclass = $propertyValue[self::ORIENT_PROPERTY_CLASS]; $embeddedMetadata = $this->dm->getMetadataFactory()->getMetadataForOClass($oclass); $doc = $embeddedMetadata->newInstance(); $embeddedData = $this->dm->getHydratorFactory()->hydrate($doc, $propertyValue, $hints); $this->uow->registerManaged($doc, null, $embeddedData); $this->metadata->reflFields[$fieldName]->setValue($document, $doc); $hydratedData[$fieldName] = $doc; continue; } } return $hydratedData; }
/** * @param UnitOfWork $uow */ public function __construct(UnitOfWork $uow) { $manager = $uow->getManager(); $this->proxyFactory = $manager->getProxyFactory(); $this->metadataFactory = $manager->getMetadataFactory(); $this->inflector = $manager->getInflector(); $this->binding = $manager->getBinding(); $this->uow = $uow; $this->clusterMap = new ClusterMap($this->binding, $manager->getCache()); $this->caster = new Caster($this, $this->inflector); $this->enableMismatchesTolerance($manager->getConfiguration()->getMismatchesTolerance()); }
/** * @inheritdoc */ public function contains($object) { if (!is_object($object)) { throw new \InvalidArgumentException(gettype($object)); } return ($this->uow->isScheduledForInsert($object) || $this->uow->isInIdentityMap($object)) && !$this->uow->isScheduledForDelete($object); }
/** * @test */ public function hydrate_contact_with_link_list() { $md = $this->manager->getClassMetadata(Stub\Linked\Contact::class); $dh = new DynamicHydrator($this->manager, $this->manager->getUnitOfWork(), $md); $c = new Stub\Linked\Contact(); $d = json_decode(<<<JSON { "@rid": "#1:1", "name": "Sydney", "phones": [ "#3:1", "#3:2" ] } JSON , true); $hd = $dh->hydrate($c, $d); $this->assertEquals(['rid', 'name', 'phones'], array_keys($hd)); $this->assertEquals('#1:1', $hd['rid']); $this->assertEquals('Sydney', $hd['name']); /** @var Stub\Linked\Phone[] $phones */ $phones = $c->getPhones()->toArray(); $this->assertCount(2, $phones); $phone = $phones[0]; $this->assertEquals('work', $phone->type); $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->uow->getDocumentState($phone)); $this->assertTrue($this->uow->isInIdentityMap($phone)); $phone = $phones[1]; $this->assertEquals('home', $phone->type); $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->uow->getDocumentState($phone)); $this->assertTrue($this->uow->isInIdentityMap($phone)); }
/** * Creates or fills a single document object from an query result. * * @param array $result The query result. * @param object $document The document object to fill, if any. * @param array $hints Hints for document creation. * * @return object The filled and managed document object or NULL, if the query result is empty. */ private function createDocument($result, $document = null, array $hints = []) { if ($result === null) { return null; } if ($document !== null) { $this->uow->registerManaged($document, $result['@rid'], null); } return $this->uow->getOrCreateDocument($result, $hints); }
/** * Prepares the array that is ready to be inserted to mongodb for a given object document. * * @param ClassMetadata $class * @param UnitOfWork $uow * @param object $document * * @return \stdClass $insertData * @throws ODMOrientDbException */ public function prepareData(ClassMetadata $class, UnitOfWork $uow, $document) { $insertData = new \stdClass(); if ($class->isEmbeddedDocument()) { $insertData->{'@type'} = 'd'; $insertData->{'@class'} = $class->getOrientClass(); $cs = $uow->getDocumentActualData($document); } else { $cs = $uow->getDocumentChangeSet($document); array_Walk($cs, function (&$val) { $val = $val[1]; }); } $mappings =& $class->fieldMappings; foreach ($cs as $name => $new) { $mapping = isset($mappings[$name]) ? $mappings[$name] : null; if ($mapping === null) { // don't store arbitrary values for now continue; } // Don't store null values unless nullable === true if ($new === null && $mapping['nullable'] === false) { continue; } $value = null; if ($new !== null) { switch (true) { // @Property case !isset($mapping['association']): $value = Type::getType($mapping['type'])->convertToDatabaseValue($new); break; case $mapping['association'] & ClassMetadata::LINK: $value = $this->getDocReference($new); break; case $mapping['association'] & ClassMetadata::LINK_MANY: // initialize the link collection if ($mapping['association'] & ClassMetadata::LINK_MAP) { $value = new \stdClass(); } else { $value = []; } break; case $mapping['association'] & ClassMetadata::EMBED: /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($new)); $value = $this->prepareData($rmd, $uow, $new); break; case $mapping['association'] & ClassMetadata::EMBED_MANY: $value = []; if ($mapping['association'] & ClassMetadata::EMBED_MAP) { foreach ($new as $k => $item) { /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($item)); $value[$k] = $this->prepareData($rmd, $uow, $item); } } else { foreach ($new as $k => $item) { /** @var ClassMetadata $rmd */ $rmd = $this->metadataFactory->getMetadataFor(get_class($item)); $value[] = $this->prepareData($rmd, $uow, $item); } } break; } } $insertData->{$mapping['name']} = $value; } return $insertData; }
/** * @return Persister\DocumentPersister */ protected function getDocumentPersister() { return $this->uow->getDocumentPersister($this->metadata->name); }