Completed
Push — master ( b6475d...698293 )
by Jesse
01:59
created

SimpleHydrator::withInstantiator()   A

Complexity

Conditions 2
Paths 1

Size

Total Lines 9
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
cc 2
eloc 4
nc 1
nop 3
1
<?php
2
3
declare(strict_types = 1);
4
5
namespace Stratadox\Hydrator;
6
7
use Closure;
8
use Stratadox\Instantiator\CannotInstantiateThis;
9
use Stratadox\Instantiator\Instantiator;
10
use Stratadox\Instantiator\ProvidesInstances;
11
use Throwable;
12
13
/**
14
 * Hydrates an object from array input.
15
 *
16
 * @package Stratadox\Hydrate
17
 * @author Stratadox
18
 */
19
final class SimpleHydrator implements Hydrates
20
{
21
    private $make;
22
    private $setter;
23
    private $observer;
24
25
    private function __construct(
26
        ProvidesInstances $instances,
27
        ObservesHydration $observer,
28
        ?Closure $setter
29
    ) {
30
        $this->make = $instances;
31
        $this->observer = $observer;
32
        $this->setter = $setter ?: function (string $attribute, $value) {
33
            $this->$attribute = $value;
34
        };
35
    }
36
37
    /**
38
     * Creates a new simple hydrator.
39
     *
40
     * @param string                 $class    The class to hydrate.
41
     * @param Closure|null           $setter   The closure that writes the values.
42
     * @param ObservesHydration|null $observer Object that gets updated with the
43
     *                                         hydrating instance.
44
     * @return self                            The hydrator.
45
     * @throws CannotInstantiateThis           When the class is not instantiable.
46
     */
47
    public static function forThe(
48
        string $class,
49
        Closure $setter = null,
50
        ObservesHydration $observer = null
51
    ): self {
52
        return new self(
53
            Instantiator::forThe($class),
54
            $observer ?: BlindObserver::add(),
55
            $setter
56
        );
57
    }
58
59
    /**
60
     * Creates a new simple hydrator with an instantiator.
61
     *
62
     * @param ProvidesInstances      $instantiator The instance provider to use.
63
     * @param Closure|null           $setter       The closure that writes the
64
     *                                             values.
65
     * @param ObservesHydration|null $observer     Object that gets updated with
66
     *                                             the hydrating instance.
67
     * @return SimpleHydrator                      The hydrator.
68
     */
69
    public static function withInstantiator(
70
        ProvidesInstances $instantiator,
71
        Closure $setter = null,
72
        ObservesHydration $observer = null
73
    ): self {
74
        return new self(
75
            $instantiator,
76
            $observer ?: BlindObserver::add(),
77
            $setter
78
        );
79
    }
80
81
    /** @inheritdoc */
82
    public function fromArray(array $data)
83
    {
84
        try {
85
            $object = $this->make->instance();
86
            $this->observer->hydrating($object);
87
            foreach ($data as $attribute => $value) {
88
                $this->setter->call($object, $attribute, $value);
89
            }
90
            return $object;
91
        } catch (Throwable $exception) {
92
            throw HydrationFailed::encountered($exception, $this->make->class());
93
        }
94
    }
95
}
96