Skip to content

Commit

Permalink
Adding setter injection
Browse files Browse the repository at this point in the history
  • Loading branch information
moufmouf committed Jul 5, 2016
1 parent c309a38 commit 1abd0dd
Show file tree
Hide file tree
Showing 4 changed files with 157 additions and 25 deletions.
106 changes: 85 additions & 21 deletions src/TdbmHydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@


use Stringy\StaticStringy;
use function Stringy\create as s;

class TdbmHydrator implements Hydrator
{
Expand All @@ -19,40 +20,52 @@ class TdbmHydrator implements Hydrator
public function hydrateNewObject(array $data, string $className)
{
$reflectionClass = new \ReflectionClass($className);
$constructor = $reflectionClass->getConstructor();
$constructorParameters = $constructor->getParameters();
$underscoredData = $this->underscoreData($data);
$parameters = [];

$underscoredData = [];
foreach ($data as $key => $value) {
$underscoredData[(string) StaticStringy::underscored($key)] = $value;
}
$constructor = $reflectionClass->getConstructor();

$parameters = [];
if ($constructor !== null) {
$constructorParameters = $constructor->getParameters();

foreach ($constructorParameters as $constructorParameter) {
$underscoredVariableName = (string) StaticStringy::underscored($constructorParameter->getName());
foreach ($constructorParameters as $constructorParameter) {
$underscoredVariableName = (string) StaticStringy::underscored($constructorParameter->getName());

if (array_key_exists($underscoredVariableName, $underscoredData)) {
$value = $underscoredData[$underscoredVariableName];
unset($underscoredData[$underscoredVariableName]);
} else {
if (!$constructorParameter->isDefaultValueAvailable()) {
throw MissingParameterException::create($constructorParameter->getName());
if (array_key_exists($underscoredVariableName, $underscoredData)) {
$value = $underscoredData[$underscoredVariableName];
unset($underscoredData[$underscoredVariableName]);
} else {
if (!$constructorParameter->isDefaultValueAvailable()) {
throw MissingParameterException::create($constructorParameter->getName());
}
$value = $constructorParameter->getDefaultValue();
}
$value = $constructorParameter->getDefaultValue();
}

// TODO: check if sub object!
$parameters[] = $value;
// TODO: check if sub object!
$parameters[] = $value;
}
}

$object = $reflectionClass->newInstanceArgs($parameters);

$this->hydrateObject($data, $object);
$this->hydrateObjectFromUnderscoredData($underscoredData, $object);

return $object;
}

/**
* Underscores the keys of the array.
*
* @param array $data
*/
private function underscoreData(array $data)
{
$underscoredData = [];
foreach ($data as $key => $value) {
$underscoredData[(string) StaticStringy::underscored($key)] = $value;
}
return $underscoredData;
}

/**
* Fills $object with $data.
Expand All @@ -62,6 +75,57 @@ public function hydrateNewObject(array $data, string $className)
*/
public function hydrateObject(array $data, $object)
{
// TODO
$underscoredData = $this->underscoreData($data);
$this->hydrateObjectFromUnderscoredData($underscoredData, $object);
}

private function hydrateObjectFromUnderscoredData(array $underscoredData, $object)
{
$reflectionClass = new \ReflectionClass($object);

$setters = $this->getSetters($reflectionClass);

foreach ($setters as $underscoredName => $setter) {

if (array_key_exists($underscoredName, $underscoredData)) {
$value = $underscoredData[$underscoredName];
unset($underscoredData[$underscoredName]);
$setterName = $setter->getName();

$object->$setterName($value);
}

// TODO: check if sub object!
}
}

/**
* Returns an array of setters reflection methods, indexed by "underscored" name.
*
* @param \ReflectionClass $reflectionClass
* @return \ReflectionMethod[]
*/
private function getSetters(\ReflectionClass $reflectionClass) {
$reflectionMethods = $reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC);

$setters = [];

foreach ($reflectionMethods as $reflectionMethod) {
$methodName = s($reflectionMethod->getName());
$parameters = $reflectionMethod->getParameters();
if ($methodName->startsWith('set') && count($parameters) >= 1) {
// Let's check that the setter has no more than 1 compulsory parameter.
array_shift($parameters);
foreach ($parameters as $optionalParameters) {
if (!$optionalParameters->isDefaultValueAvailable()) {
continue 2;
}
}
$underscored = (string) $methodName->substr(3)->underscored();
$setters[$underscored] = $reflectionMethod;
}
}

return $setters;
}
}
19 changes: 18 additions & 1 deletion tests/Fixtures/FixtureA.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ class FixtureA
private $one;
private $two;
private $three;
private $four;

/**
* FixtureA constructor.
Expand Down Expand Up @@ -52,7 +53,23 @@ public function getThree()
*/
public function setThree($three)
{
$this->three = $three;
throw new \Exception('This should never be called.');
}

/**
* @return mixed
*/
public function getFour()
{
return $this->four;
}

/**
* @param mixed $four
*/
public function setFour($four)
{
$this->four = $four;
}

}
26 changes: 26 additions & 0 deletions tests/Fixtures/FixtureB.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<?php


namespace Mouf\Hydrator\Fixtures;


class FixtureB
{
private $one;

/**
* @return mixed
*/
public function getOne()
{
return $this->one;
}

/**
* @param mixed $one
*/
public function setOne($one, $two)
{
$this->one = $one;
}
}
31 changes: 28 additions & 3 deletions tests/TdbmHydratorTest.php
Original file line number Diff line number Diff line change
@@ -1,25 +1,26 @@
<?php


namespace Mouf\Hydrator;


use Mouf\Hydrator\Fixtures\FixtureA;
use Mouf\Hydrator\Fixtures\FixtureB;

class TdbmHydratorTest extends \PHPUnit_Framework_TestCase
{
public function testHydrate()
public function testHydrateWithConstructor()
{
$hydrator = new TdbmHydrator();
$a = $hydrator->hydrateNewObject([
'one' => 1,
'two' => 2,
'four' => 4
], FixtureA::class);

/** @var $a FixtureA */
$this->assertEquals(1, $a->getOne());
$this->assertEquals(2, $a->getTwo());
$this->assertEquals(3, $a->getThree());
$this->assertEquals(4, $a->getFour());
}

public function testHydrateNull()
Expand All @@ -44,6 +45,30 @@ public function testMissingCompulsoryParameter()
$hydrator->hydrateNewObject([
'one' => 1,
], FixtureA::class);
}

public function testNoHydrateSettersWithMultipleValues()
{
$hydrator = new TdbmHydrator();
$b = $hydrator->hydrateNewObject([
'one' => 1,
], FixtureB::class);

/** @var $b FixtureB */
$this->assertEquals(null, $b->getOne());
}

public function testHydrate()
{
$hydrator = new TdbmHydrator();
$a = new FixtureA(1 , 2);

$hydrator->hydrateObject([
'four' => 4
], $a);

/** @var $a FixtureA */
$this->assertEquals(4, $a->getFour());
}

}

0 comments on commit 1abd0dd

Please sign in to comment.