/** * @test */ public function hydrate_contact_with_link() { $c = new Stub\Linked\Contact(); $md = $this->manager->getClassMetadata(Stub\Linked\Contact::class); $dh = new DynamicHydrator($this->manager, $this->manager->getUnitOfWork(), $md); $d = json_decode(<<<JSON { "@rid": "#1:1", "name": "Sydney", "email": "#2:1" } JSON , true); $hd = $dh->hydrate($c, $d); $this->uow->registerManaged($c, "#1:1", $hd); $this->assertEquals(['rid', 'name', 'email', 'phones'], array_keys($hd)); $this->assertEquals('#1:1', $hd['rid']); $this->assertEquals('Sydney', $hd['name']); $this->assertNotNull($hd['email']); $email = $c->getEmail(); $this->assertNotNull($email); $this->assertEquals('work', $email->type); $this->assertEquals('*****@*****.**', $email->email); $this->assertEquals(UnitOfWork::STATE_MANAGED, $this->uow->getDocumentState($email)); $this->assertTrue($this->uow->isInIdentityMap($email)); return [$c, $email]; }
/** * @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; }
/** * 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); }
/** * Returns a reference to an entity. It will be lazily and transparently * loaded if anything other than the identifier is touched. * * @param $rid * * @return Proxy */ public function getReference($rid) { $oclass = $this->clusterMap->identifyClass($rid); $md = $this->metadataFactory->getMetadataForOClass($oclass); if ($document = $this->uow->tryGetById($rid, $md)) { return $document; } $document = $this->proxyFactory->getProxy($md->name, [$md->getRidPropertyName() => $rid]); $this->uow->registerManaged($document, $rid, []); return $document; }