Skip to content

Commit 20ca4fe

Browse files
authored
Merge pull request #18 from nutgram/improve_resolvers
2 parents 4a7164b + a1c9c90 commit 20ca4fe

File tree

4 files changed

+48
-16
lines changed

4 files changed

+48
-16
lines changed

src/Annotation/ConcreteResolver.php

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,20 @@
1212
#[Attribute(Attribute::TARGET_CLASS)]
1313
abstract class ConcreteResolver
1414
{
15+
protected array $concretes = [];
16+
1517
/**
1618
* @param array $data
1719
*
18-
* @return string
20+
* @return string|null
21+
*/
22+
abstract public function concreteFor(array $data): ?string;
23+
24+
/**
25+
* @return array
1926
*/
20-
abstract public function getConcreteClass(array $data): string;
27+
public function getConcretes(): array
28+
{
29+
return array_values($this->concretes);
30+
}
2131
}

src/Hydrator.php

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ public function __construct(?ContainerInterface $container = null)
5555
* @param class-string<T>|T $object
5656
* @param array|object $data
5757
*
58-
* @throws InvalidArgumentException
59-
* If the data isn't valid.
6058
* @throws Exception\UntypedPropertyException
6159
* If one of the object properties isn't typed.
6260
* @throws Exception\UnsupportedPropertyTypeException
@@ -67,6 +65,8 @@ public function __construct(?ContainerInterface $container = null)
6765
* If the given data contains an invalid value.
6866
* @throws Exception\HydrationException
6967
* If the object cannot be hydrated.
68+
* @throws InvalidArgumentException
69+
* If the data isn't valid.
7070
*
7171
* @return T
7272
*
@@ -150,10 +150,10 @@ public function hydrate(string|object $object, array|object $data): object
150150
* @param string $json
151151
* @param ?int $flags
152152
*
153-
* @throws InvalidArgumentException
154-
* If the JSON cannot be decoded.
155153
* @throws Exception\HydrationException
156154
* If the object cannot be hydrated.
155+
* @throws InvalidArgumentException
156+
* If the JSON cannot be decoded.
157157
*
158158
* @return T
159159
*
@@ -179,14 +179,26 @@ public function hydrateWithJson(string|object $object, string $json, ?int $flags
179179
return $this->hydrate($object, $data);
180180
}
181181

182+
/**
183+
* @param class-string|object $object
184+
*
185+
* @throws \ReflectionException
186+
*
187+
* @return object|null
188+
*/
189+
public function getConcreteResolverFor(string|object $object): ?ConcreteResolver
190+
{
191+
return $this->getAttributeInstance(new ReflectionClass($object), ConcreteResolver::class, ReflectionAttribute::IS_INSTANCEOF);
192+
}
193+
182194
/**
183195
* Initializes the given object.
184196
*
185197
* @param class-string<T>|T $object
186198
*
199+
* @throws InvalidArgumentException
187200
* @throws ContainerExceptionInterface
188201
* If the object cannot be initialized.
189-
* @throws InvalidArgumentException
190202
*
191203
* @return T
192204
*
@@ -218,7 +230,7 @@ private function initializeObject(string|object $object, array|object $data): ob
218230
));
219231
}
220232

221-
return $this->initializeObject($attribute->getConcreteClass($data), $data);
233+
return $this->initializeObject($attribute->concreteFor($data), $data);
222234
}
223235

224236
// if we have a container, get the instance through it
@@ -268,10 +280,10 @@ private function getAttributeInstance(ReflectionProperty|ReflectionClass $target
268280
* @param ReflectionNamedType $type
269281
* @param mixed $value
270282
*
271-
* @throws Exception\UnsupportedPropertyTypeException
272-
* If the given property contains an unsupported type.
273283
* @throws Exception\InvalidValueException
274284
* If the given value isn't valid.
285+
* @throws Exception\UnsupportedPropertyTypeException
286+
* If the given property contains an unsupported type.
275287
*
276288
* @return void
277289
*/

tests/Fixtures/Resolver/AppleResolver.php

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@
1010
#[Attribute(Attribute::TARGET_CLASS)]
1111
class AppleResolver extends ConcreteResolver
1212
{
13-
public function getConcreteClass(array $data): string
13+
protected array $concretes = [
14+
'jack' => AppleJack::class,
15+
'sauce' => AppleSauce::class,
16+
];
17+
18+
public function concreteFor(array $data): ?string
1419
{
15-
return match ($data['type']) {
16-
'jack' => AppleJack::class,
17-
'sauce' => AppleSauce::class,
18-
default => throw new Exception('Invalid apple type'),
19-
};
20+
return $this->concretes[$data['type']] ?? null;
2021
}
2122
}

tests/HydratorTest.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
use SergiX44\Hydrator\Tests\Fixtures\DI\Tree;
1515
use SergiX44\Hydrator\Tests\Fixtures\ObjectWithAbstract;
1616
use SergiX44\Hydrator\Tests\Fixtures\ObjectWithInvalidAbstract;
17+
use SergiX44\Hydrator\Tests\Fixtures\Resolver\AppleResolver;
1718
use SergiX44\Hydrator\Tests\Fixtures\Store\Apple;
1819
use SergiX44\Hydrator\Tests\Fixtures\Store\AppleJack;
1920
use SergiX44\Hydrator\Tests\Fixtures\Store\AppleSauce;
@@ -764,6 +765,14 @@ public function testHydrateAbstractObjectWithoutInterface(): void
764765
(new Hydrator())->hydrate(Fruit::class, ['name' => 'apple']);
765766
}
766767

768+
public function testItReturnsTheConcreteResolver(): void
769+
{
770+
$resolver = (new Hydrator())->getConcreteResolverFor(Apple::class);
771+
772+
$this->assertInstanceOf(AppleResolver::class, $resolver);
773+
$this->assertSame([AppleJack::class, AppleSauce::class], $resolver->getConcretes());
774+
}
775+
767776
public function testHydrateAbstractProperty(): void
768777
{
769778
$o = (new Hydrator())->hydrate(new ObjectWithAbstract(), [

0 commit comments

Comments
 (0)