Completed
Push — master ( c2d23a...f43081 )
by Jesse
02:42
created

SimpleHydrator::classFor()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

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