Skip to content

Commit

Permalink
Merge pull request #10 from nutgram/container
Browse files Browse the repository at this point in the history
Ability to resolve objects through container
  • Loading branch information
Lukasss93 authored Nov 14, 2022
2 parents 0a76de5 + b75345e commit 7ca00bf
Show file tree
Hide file tree
Showing 8 changed files with 166 additions and 3 deletions.
6 changes: 4 additions & 2 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,12 @@
}
],
"require": {
"php": "^8.0"
"php": "^8.0",
"psr/container": "^1.1 || ^2.0"
},
"require-dev": {
"phpunit/phpunit": "~9.5.0"
"phpunit/phpunit": "~9.5.0",
"league/container": "^4.2"
},
"autoload": {
"psr-4": {
Expand Down
17 changes: 16 additions & 1 deletion src/Hydrator.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,8 @@
use function is_object;
use function is_string;
use function is_subclass_of;
use Psr\Container\ContainerExceptionInterface;
use Psr\Container\ContainerInterface;
use ReflectionAttribute;
use ReflectionClass;
use ReflectionEnum;
Expand All @@ -40,6 +42,13 @@

class Hydrator implements HydratorInterface
{
protected ?ContainerInterface $container = null;

public function __construct(?ContainerInterface $container = null)
{
$this->container = $container;
}

/**
* Hydrates the given object with the given data.
*
Expand Down Expand Up @@ -175,8 +184,9 @@ public function hydrateWithJson(string|object $object, string $json, ?int $flags
*
* @param class-string<T>|T $object
*
* @throws ContainerExceptionInterface
* If the object cannot be initialized.
* @throws InvalidArgumentException
* If the object cannot be initialized.
*
* @return T
*
Expand Down Expand Up @@ -211,6 +221,11 @@ private function initializeObject(string|object $object, array|object $data): ob
return $this->initializeObject($attribute->getConcreteClass($data), $data);
}

// if we have a container, get the instance through it
if ($this->container !== null) {
return $this->container->get($object);
}

$constructor = $reflectionClass->getConstructor();
if (isset($constructor) && $constructor->getNumberOfRequiredParameters() > 0) {
throw new InvalidArgumentException(sprintf(
Expand Down
23 changes: 23 additions & 0 deletions tests/Fixtures/DI/Leaves.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace SergiX44\Hydrator\Tests\Fixtures\DI;

class Leaves
{
public int $n;

private Sun|null $sun = null;

public function __construct(?Sun $sun = null)
{
$this->sun = $sun;
}

/**
* @return Sun|null
*/
public function getSun(): ?Sun
{
return $this->sun;
}
}
21 changes: 21 additions & 0 deletions tests/Fixtures/DI/Sun.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

namespace SergiX44\Hydrator\Tests\Fixtures\DI;

class Sun
{
private string $from;

public function __construct(string $from)
{
$this->from = $from;
}

/**
* @return string
*/
public function getFrom(): string
{
return $this->from;
}
}
27 changes: 27 additions & 0 deletions tests/Fixtures/DI/Tree.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
<?php

namespace SergiX44\Hydrator\Tests\Fixtures\DI;

class Tree
{
public string $name;

public Wood $wood;

public Leaves $leaves;

private Sun|null $sun = null;

public function __construct(?Sun $sun = null)
{
$this->sun = $sun;
}

/**
* @return Sun|null
*/
public function getSun(): ?Sun
{
return $this->sun;
}
}
23 changes: 23 additions & 0 deletions tests/Fixtures/DI/Wood.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
<?php

namespace SergiX44\Hydrator\Tests\Fixtures\DI;

class Wood
{
public int $kg;

private Sun|null $sun = null;

public function __construct(?Sun $sun = null)
{
$this->sun = $sun;
}

/**
* @return Sun|null
*/
public function getSun(): ?Sun
{
return $this->sun;
}
}
17 changes: 17 additions & 0 deletions tests/Fixtures/ObjectWithMissingData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

namespace SergiX44\Hydrator\Tests\Fixtures;

use SergiX44\Hydrator\Tests\Fixtures\Store\Tag;

final class ObjectWithMissingData
{
public string $name;

protected ?Tag $tag = null;

public function getTag(): ?Tag
{
return $this->tag;
}
}
35 changes: 35 additions & 0 deletions tests/HydratorTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,11 +3,15 @@
namespace SergiX44\Hydrator\Tests;

use InvalidArgumentException;
use League\Container\Container;
use League\Container\ReflectionContainer;
use PHPUnit\Framework\TestCase;
use SergiX44\Hydrator\Exception;
use SergiX44\Hydrator\Exception\InvalidObjectException;
use SergiX44\Hydrator\Hydrator;
use SergiX44\Hydrator\HydratorInterface;
use SergiX44\Hydrator\Tests\Fixtures\DI\Sun;
use SergiX44\Hydrator\Tests\Fixtures\DI\Tree;
use SergiX44\Hydrator\Tests\Fixtures\ObjectWithAbstract;
use SergiX44\Hydrator\Tests\Fixtures\ObjectWithInvalidAbstract;
use SergiX44\Hydrator\Tests\Fixtures\Store\Apple;
Expand Down Expand Up @@ -786,4 +790,35 @@ public function testHydrateInvalidAbstractObject(): void
],
]);
}

public function testHydrateWithContainer(): void
{
$sun = new Sun('andromeda');

$container = new Container();
$container->delegate(new ReflectionContainer());
$container->addShared(Sun::class, $sun);

$hydrator = new Hydrator($container);

$o = $hydrator->hydrate(Tree::class, [
'name' => 'foo',
'leaves' => [
'n' => 100,
],
'wood' => [
'kg' => 120,
],
]);

$this->assertSame('foo', $o->name);
$this->assertSame(100, $o->leaves->n);
$this->assertSame(120, $o->wood->kg);
$this->assertNotNull($o->getSun());
$this->assertNotNull($o->leaves->getSun());
$this->assertNotNull($o->wood->getSun());
$this->assertSame($sun, $o->getSun());
$this->assertSame($sun, $o->leaves->getSun());
$this->assertSame($sun, $o->wood->getSun());
}
}

0 comments on commit 7ca00bf

Please sign in to comment.