Skip to content

Commit

Permalink
Fix closure hydrator: public relations are hydrated like private ones…
Browse files Browse the repository at this point in the history
… now. There are a logic related to ReferenceInterface hydrating
  • Loading branch information
roxblnfk committed Jun 19, 2023
1 parent d957fb5 commit 52e0043
Show file tree
Hide file tree
Showing 3 changed files with 47 additions and 47 deletions.
76 changes: 40 additions & 36 deletions src/Mapper/Proxy/Hydrator/ClosureHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,56 +83,60 @@ private function setEntityProperties(array $properties, object $object, array &$
}

/**
* Map private entity relations
* Map private relations of non-proxy entity
*/
private function setRelationProperties(array $properties, RelationMap $relMap, object $object, array &$data): void
{
$refl = new \ReflectionClass($object);
$setter = static function (object $object, array $props, array &$data) use ($refl, $relMap): void {
foreach ($props as $property) {
if (!\array_key_exists($property, $data)) {
continue;
}

foreach ($properties as $class => $props) {
if ($class === '') {
continue;
}

Closure::bind(static function (object $object, array $props, array &$data) use ($refl, $relMap): void {
foreach ($props as $property) {
if (!\array_key_exists($property, $data)) {
continue;
}

$value = $data[$property];
$value = $data[$property];

if ($value instanceof ReferenceInterface) {
$prop = $refl->getProperty($property);
if ($value instanceof ReferenceInterface) {
$prop = $refl->getProperty($property);

if ($prop->hasType()) {
/** @var \ReflectionNamedType[] $types */
$types = $prop->getType() instanceof \ReflectionUnionType
? $prop->getType()->getTypes()
: [$prop->getType()];
if ($prop->hasType()) {
// todo: we can cache this
/** @var \ReflectionNamedType[] $types */
$types = $prop->getType() instanceof \ReflectionUnionType
? $prop->getType()->getTypes()
: [$prop->getType()];

foreach ($types as $type) {
$c = $type->getName();
if ($c === 'object' || $value instanceof $c) {
$object->{$property} = $value;
unset($data[$property]);
foreach ($types as $type) {
$c = $type->getName();
if ($c === 'object' || $value instanceof $c) {
$object->{$property} = $value;
unset($data[$property]);

// go to next property
continue 2;
}
// go to next property
continue 2;
}
}

$relation = $relMap->getRelations()[$property] ?? null;
if ($relation !== null) {
$value = $relation->collect($relation->resolve($value, true));
}
$relation = $relMap->getRelations()[$property] ?? null;
if ($relation !== null) {
$value = $relation->collect($relation->resolve($value, true));
}
}

$object->{$property} = $value;
unset($data[$property]);
}
}, null, $class)($object, $props, $data);

$object->{$property} = $value;
unset($data[$property]);
}
};

foreach ($properties as $class => $props) {
if ($class === '') {
// Hydrate public properties
$setter($object, $props, $data);
continue;
}

Closure::bind($setter, null, $class)($object, $props, $data);
}
}
}
2 changes: 1 addition & 1 deletion src/Mapper/StdMapper.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ public function hydrate($entity, array $data): object
{
$relations = $this->relationMap->getRelations();
foreach ($data as $k => $v) {
if ($v instanceof ReferenceInterface && array_key_exists($k, $relations)) {
if ($v instanceof ReferenceInterface && \array_key_exists($k, $relations)) {
$relation = $relations[$k];
$relation->resolve($v, false);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ public function setUp(): void
// Init DB
parent::setUp();
$this->makeTables();
$this->fillData();

$this->loadSchema(__DIR__ . '/schema.php');
}
Expand All @@ -33,8 +32,6 @@ public function testSelect(): void
$account = new Entity\Account($uuid, 'test@mail.com', \md5('password'));
$identity->profile = $profile;
$identity->account = $account;
$profile->identity = $identity;
$account->identity = $identity;

$this->save($identity);

Expand All @@ -56,6 +53,9 @@ public function testSelect(): void
// Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity\Profile::$identity of type
// Cycle\ORM\Tests\Functional\Driver\Common\Integration\Case416\Entity\Identity
$this->assertTrue(true);

// To avoid `Entity and State are not in sync` exception
$this->orm->getHeap()->clean();
}

private function makeTables(): void
Expand All @@ -69,9 +69,9 @@ private function makeTables(): void

$this->makeTable(Entity\Account::ROLE, [
'uuid' => 'string,primary',
'email' => 'datetime',
'password_hash' => 'datetime',
'updated_at' => 'datetime,nullable',
'email' => 'string',
'password_hash' => 'string',
'updated_at' => 'datetime',
]);
$this->makeFK(
Entity\Account::ROLE,
Expand All @@ -97,8 +97,4 @@ private function makeTables(): void
'NO ACTION',
);
}

private function fillData(): void
{
}
}

0 comments on commit 52e0043

Please sign in to comment.