Skip to content
This repository was archived by the owner on Jan 24, 2020. It is now read-only.

Commit 81edaac

Browse files
committed
Move hotfix from DoctrineModule 2.1.8: hydration with nested entities
See: doctrine/DoctrineModule#663
1 parent bd2cdf5 commit 81edaac

File tree

3 files changed

+142
-1
lines changed

3 files changed

+142
-1
lines changed

src/DoctrineObject.php

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -318,6 +318,8 @@ protected function hydrateByValue(array $data, $object)
318318

319319
$object->$setter($this->hydrateValue($field, $value, $data));
320320
}
321+
322+
$this->metadata = $metadata;
321323
}
322324

323325
return $object;
@@ -365,6 +367,8 @@ protected function hydrateByReference(array $data, $object)
365367
} else {
366368
$reflProperty->setValue($object, $this->hydrateValue($field, $value, $data));
367369
}
370+
371+
$this->metadata = $metadata;
368372
}
369373

370374
return $object;

test/Assets/OneToOneEntity.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
namespace DoctrineTest\Zend\Hydrator\Assets;
66

7+
use DateTime;
8+
79
class OneToOneEntity
810
{
911
/**
@@ -16,6 +18,11 @@ class OneToOneEntity
1618
*/
1719
protected $toOne;
1820

21+
/**
22+
* @var DateTime
23+
*/
24+
protected $createdAt;
25+
1926

2027
public function setId($id)
2128
{
@@ -47,4 +54,14 @@ public function getToOne($modifyValue = true)
4754

4855
return $this->toOne;
4956
}
57+
58+
public function setCreatedAt(DateTime $createdAt)
59+
{
60+
$this->createdAt = $createdAt;
61+
}
62+
63+
public function getCreatedAt()
64+
{
65+
return $this->createdAt;
66+
}
5067
}

test/DoctrineObjectTest.php

Lines changed: 121 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use InvalidArgumentException;
1515
use PHPUnit\Framework\TestCase;
1616
use PHPUnit_Framework_MockObject_MockObject;
17+
use Prophecy\Argument;
1718
use ReflectionClass;
1819
use Zend\Hydrator\NamingStrategy\UnderscoreNamingStrategy;
1920
use Zend\Hydrator\Strategy\StrategyInterface;
@@ -2649,7 +2650,7 @@ public function testOverrideDefaultStrategy()
26492650
/**
26502651
* https://github.com/doctrine/DoctrineModule/issues/639
26512652
*/
2652-
public function testStrategyWithArray()
2653+
public function testStrategyWithArrayByValue()
26532654
{
26542655
$entity = new Assets\SimpleEntity();
26552656

@@ -2672,4 +2673,123 @@ public function hydrate($value) : string
26722673

26732674
$this->assertEquals('complex,value', $entity->getField());
26742675
}
2676+
2677+
public function testStrategyWithArrayByReference()
2678+
{
2679+
$entity = new Assets\SimpleEntity();
2680+
2681+
$data = ['field' => ['complex', 'value']];
2682+
$this->configureObjectManagerForSimpleEntity();
2683+
$this->hydratorByReference->addStrategy('field', new class implements StrategyInterface {
2684+
public function extract($value) : array
2685+
{
2686+
return explode(',', $value);
2687+
}
2688+
2689+
public function hydrate($value) : string
2690+
{
2691+
return implode(',', $value);
2692+
}
2693+
2694+
});
2695+
2696+
$this->hydratorByReference->hydrate($data, $entity);
2697+
2698+
$this->assertSame('complex,value', $entity->getField());
2699+
}
2700+
2701+
private function getObjectManagerForNestedHydration()
2702+
{
2703+
$oneToOneMetadata = $this->prophesize(ClassMetadata::class);
2704+
$oneToOneMetadata->getName()->willReturn(Assets\OneToOneEntity::class);
2705+
$oneToOneMetadata->getFieldNames()->willReturn(['id', 'toOne', 'createdAt']);
2706+
$oneToOneMetadata->getAssociationNames()->willReturn(['toOne']);
2707+
$oneToOneMetadata->getTypeOfField('id')->willReturn('integer');
2708+
$oneToOneMetadata->getTypeOfField('toOne')->willReturn(Assets\ByValueDifferentiatorEntity::class);
2709+
$oneToOneMetadata->getTypeOfField('createdAt')->willReturn('datetime');
2710+
$oneToOneMetadata->hasAssociation('id')->willReturn(false);
2711+
$oneToOneMetadata->hasAssociation('toOne')->willReturn(true);
2712+
$oneToOneMetadata->hasAssociation('createdAt')->willReturn(false);
2713+
$oneToOneMetadata->isSingleValuedAssociation('toOne')->willReturn(true);
2714+
$oneToOneMetadata->isCollectionValuedAssociation('toOne')->willReturn(false);
2715+
$oneToOneMetadata->getAssociationTargetClass('toOne')->willReturn(Assets\ByValueDifferentiatorEntity::class);
2716+
$oneToOneMetadata->getReflectionClass()->willReturn(new ReflectionClass(Assets\OneToOneEntity::class));
2717+
$oneToOneMetadata->getIdentifier()->willReturn(['id']);
2718+
$oneToOneMetadata->getIdentifierFieldNames(Argument::type(Assets\OneToOneEntity::class))->willReturn(['id']);
2719+
2720+
$byValueDifferentiatorEntity = $this->prophesize(ClassMetadata::class);
2721+
$byValueDifferentiatorEntity->getName()->willReturn(Assets\ByValueDifferentiatorEntity::class);
2722+
$byValueDifferentiatorEntity->getAssociationNames()->willReturn([]);
2723+
$byValueDifferentiatorEntity->getFieldNames()->willReturn(['id', 'field']);
2724+
$byValueDifferentiatorEntity->getTypeOfField('id')->willReturn('integer');
2725+
$byValueDifferentiatorEntity->getTypeOfField('field')->willReturn('string');
2726+
$byValueDifferentiatorEntity->hasAssociation(Argument::any())->willReturn(false);
2727+
$byValueDifferentiatorEntity->getIdentifier()->willReturn(['id']);
2728+
$byValueDifferentiatorEntity
2729+
->getIdentifierFieldNames(Argument::type(Assets\ByValueDifferentiatorEntity::class))
2730+
->willReturn(['id']);
2731+
$byValueDifferentiatorEntity
2732+
->getReflectionClass()
2733+
->willReturn(new ReflectionClass(Assets\ByValueDifferentiatorEntity::class));
2734+
2735+
$objectManager = $this->prophesize(ObjectManager::class);
2736+
$objectManager
2737+
->getClassMetadata(Assets\OneToOneEntity::class)
2738+
->will([$oneToOneMetadata, 'reveal']);
2739+
$objectManager
2740+
->getClassMetadata(Assets\ByValueDifferentiatorEntity::class)
2741+
->will([$byValueDifferentiatorEntity, 'reveal']);
2742+
$objectManager->find(Assets\OneToOneEntity::class, ['id' => 12])->willReturn(false);
2743+
$objectManager->find(Assets\ByValueDifferentiatorEntity::class, ['id' => 13])->willReturn(false);
2744+
2745+
return $objectManager->reveal();
2746+
}
2747+
2748+
public function testNestedHydrationByValue()
2749+
{
2750+
$objectManager = $this->getObjectManagerForNestedHydration();
2751+
$hydrator = new DoctrineObjectHydrator($objectManager, true);
2752+
$entity = new Assets\OneToOneEntity();
2753+
2754+
$data = [
2755+
'id' => 12,
2756+
'toOne' => [
2757+
'id' => 13,
2758+
'field' => 'value',
2759+
],
2760+
'createdAt' => '2019-01-24 12:00:00',
2761+
];
2762+
2763+
$hydrator->hydrate($data, $entity);
2764+
2765+
$this->assertSame(12, $entity->getId());
2766+
$this->assertInstanceOf(Assets\ByValueDifferentiatorEntity::class, $entity->getToOne(false));
2767+
$this->assertSame(13, $entity->getToOne(false)->getId());
2768+
$this->assertSame('Modified from setToOne setter', $entity->getToOne(false)->getField(false));
2769+
$this->assertSame('2019-01-24 12:00:00', $entity->getCreatedAt()->format('Y-m-d H:i:s'));
2770+
}
2771+
2772+
public function testNestedHydrationByReference()
2773+
{
2774+
$objectManager = $this->getObjectManagerForNestedHydration();
2775+
$hydrator = new DoctrineObjectHydrator($objectManager, false);
2776+
$entity = new Assets\OneToOneEntity();
2777+
2778+
$data = [
2779+
'id' => 12,
2780+
'toOne' => [
2781+
'id' => 13,
2782+
'field' => 'value',
2783+
],
2784+
'createdAt' => '2019-01-24 12:00:00',
2785+
];
2786+
2787+
$hydrator->hydrate($data, $entity);
2788+
2789+
$this->assertSame(12, $entity->getId());
2790+
$this->assertInstanceOf(Assets\ByValueDifferentiatorEntity::class, $entity->getToOne(false));
2791+
$this->assertSame(13, $entity->getToOne(false)->getId());
2792+
$this->assertSame('value', $entity->getToOne(false)->getField(false));
2793+
$this->assertSame('2019-01-24 12:00:00', $entity->getCreatedAt()->format('Y-m-d H:i:s'));
2794+
}
26752795
}

0 commit comments

Comments
 (0)