Completed
Push — master ( 29674e...407897 )
by Jesse
07:39
created

VariadicConstructor   A

Complexity

Total Complexity 6

Size/Duplication

Total Lines 45
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
wmc 6
dl 0
loc 45
rs 10
c 0
b 0
f 0

5 Methods

Rating   Name   Duplication   Size   Complexity  
A forThe() 0 3 1
A newObjectFrom() 0 7 1
A classFor() 0 3 1
A fromArray() 0 6 2
A __construct() 0 3 1
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\Hydrator;
5
6
use ReflectionException;
7
use ReflectionObject as Reflected;
8
use Stratadox\Instantiator\CannotInstantiateThis;
9
use Stratadox\Instantiator\Instantiator;
10
use Stratadox\Instantiator\ProvidesInstances;
11
use Throwable;
12
13
/**
14
 * Hydrates an object by calling its constructor with squashed array input.
15
 *
16
 * @package Stratadox\Hydrate
17
 * @author  Stratadox
18
 */
19
final class VariadicConstructor implements Hydrates
20
{
21
    private $make;
22
23
    private function __construct(ProvidesInstances $forTheClass)
24
    {
25
        $this->make = $forTheClass;
26
    }
27
28
    /**
29
     * Creates a new variadic constructor calling hydrator.
30
     *
31
     * @param string $class          The class to hydrate.
32
     * @return Hydrates              The variadic construction calling hydrator.
33
     * @throws CannotInstantiateThis When the class is not instantiable.
34
     */
35
    public static function forThe(string $class): Hydrates
36
    {
37
        return new self(Instantiator::forThe($class));
38
    }
39
40
    /** @inheritdoc */
41
    public function fromArray(array $input)
42
    {
43
        try {
44
            return $this->newObjectFrom($input);
45
        } catch (Throwable $exception) {
46
            throw HydrationFailed::encountered($exception, $this->make->class());
47
        }
48
    }
49
50
    /** @throws CannotInstantiateThis|ReflectionException */
51
    private function newObjectFrom(array $input)
52
    {
53
        $object = $this->make->instance();
54
        $constructor = (new Reflected($object))->getMethod('__construct');
55
        $constructor->setAccessible(true);
56
        $constructor->invoke($object, ...$input);
57
        return $object;
58
    }
59
60
    /** @inheritdoc */
61
    public function classFor(array $input): string
62
    {
63
        return $this->make->class();
64
    }
65
}
66