Passed
Push — master ( a5d157...2a272c )
by Jesse
04:07
created

HasManyProxies::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 4
nc 1
nop 4
dl 0
loc 10
rs 9.4285
c 0
b 0
f 0
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Stratadox\Hydration\Mapping\Property\Relationship;
6
7
use Stratadox\Hydration\Mapping\Property\MissingTheKey;
8
use Stratadox\HydrationMapping\ExposesDataKey;
9
use Stratadox\Hydrator\Hydrates;
10
use Stratadox\Proxy\ProducesProxies;
11
use Throwable;
12
13
/**
14
 * Maps a number to a collection of proxies in an object property.
15
 *
16
 * @package Stratadox\Hydrate
17
 * @author Stratadox
18
 */
19
final class HasManyProxies implements ExposesDataKey
20
{
21
    private $name;
22
    private $key;
23
    private $collection;
24
    private $proxyBuilder;
25
26
    private function __construct(
27
        string $name,
28
        string $dataKey,
29
        Hydrates $collectionHydrator,
30
        ProducesProxies $proxyBuilder
31
    ) {
32
        $this->name = $name;
33
        $this->key = $dataKey;
34
        $this->collection = $collectionHydrator;
35
        $this->proxyBuilder = $proxyBuilder;
36
    }
37
38
    /**
39
     * Create a new lazily loaded has-many mapping.
40
     *
41
     * @param string          $name         The name of both the key and the property.
42
     * @param Hydrates        $collection   The hydrator for the collection.
43
     * @param ProducesProxies $proxyBuilder The proxy builder.
44
     * @return self                         The lazy has-many mapping.
45
     */
46
    public static function inProperty(
47
        string $name,
48
        Hydrates $collection,
49
        ProducesProxies $proxyBuilder
50
    ) : self
51
    {
52
        return new self($name, $name, $collection, $proxyBuilder);
53
    }
54
55
    /**
56
     * Create a new lazily loading has-many mapping, using the data from a
57
     * specific key.
58
     *
59
     * @param string          $name         The name of both the key and the property.
60
     * @param string          $key          The array key to use.
61
     * @param Hydrates        $collection   The hydrator for the collection.
62
     * @param ProducesProxies $proxyBuilder The proxy builder.
63
     * @return self                         The lazy has-many mapping.
64
     */
65
    public static function inPropertyWithDifferentKey(
66
        string $name,
67
        string $key,
68
        Hydrates $collection,
69
        ProducesProxies $proxyBuilder
70
    ) : self
71
    {
72
        return new self($name, $key, $collection, $proxyBuilder);
73
    }
74
75
    public function name() : string
76
    {
77
        return $this->name;
78
    }
79
80
    public function key() : string
81
    {
82
        return $this->key;
83
    }
84
85
    public function value(array $data, $owner = null)
86
    {
87
        if (!array_key_exists($this->key(), $data)) {
88
            throw MissingTheKey::inTheInput($data, $this, $this->key());
89
        }
90
        $amount = $data[$this->key()];
91
        try {
92
            $proxies = [];
93
            for ($i = 0; $i < $amount; ++$i) {
94
                $proxies[] = $this->proxyBuilder->createFor($owner, $this->name(), $i);
95
            }
96
        } catch (Throwable $exception) {
97
            throw ProxyProductionFailed::tryingToProduceFor($this, $exception);
98
        }
99
        try {
100
            return $this->collection->fromArray($proxies);
101
        } catch (Throwable $exception) {
102
            throw CollectionMappingFailed::tryingToMapCollection($this, $exception);
103
        }
104
    }
105
}
106