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

HasManyNested::name()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
rs 10
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 Throwable;
11
12
/**
13
 * Maps a nested data structure to a collection in an object property.
14
 *
15
 * @package Stratadox\Hydrate
16
 * @author Stratadox
17
 */
18
final class HasManyNested implements ExposesDataKey
19
{
20
    private $name;
21
    private $key;
22
    private $collection;
23
    private $item;
24
25
    private function __construct(
26
        string $name,
27
        string $dataKey,
28
        Hydrates $collection,
29
        Hydrates $item
30
    ) {
31
        $this->name = $name;
32
        $this->key = $dataKey;
33
        $this->collection = $collection;
34
        $this->item = $item;
35
    }
36
37
    /**
38
     * Create a new nested has-many mapping.
39
     *
40
     * @param string   $name       The name of both the key and the property.
41
     * @param Hydrates $collection The hydrator for the collection.
42
     * @param Hydrates $item       The hydrator for the individual items.
43
     * @return self                The nested has-many mapping.
44
     */
45
    public static function inProperty(
46
        string $name,
47
        Hydrates $collection,
48
        Hydrates $item
49
    ) : self
50
    {
51
        return new self($name, $name, $collection, $item);
52
    }
53
54
    /**
55
     * Create a new nested has-many mapping, using the data from a specific key.
56
     *
57
     * @param string   $name       The name of the property.
58
     * @param string   $key        The name of the key.
59
     * @param Hydrates $collection The hydrator for the collection.
60
     * @param Hydrates $item       The hydrator for the individual items.
61
     * @return self                The nested has-many mapping.
62
     */
63
    public static function inPropertyWithDifferentKey(
64
        string $name,
65
        string $key,
66
        Hydrates $collection,
67
        Hydrates $item
68
    ) : self
69
    {
70
        return new self($name, $key, $collection, $item);
71
    }
72
73
    public function name() : string
74
    {
75
        return $this->name;
76
    }
77
78
    public function key() : string
79
    {
80
        return $this->key;
81
    }
82
83
    public function value(array $data, $owner = null)
84
    {
85
        if (!array_key_exists($this->key(), $data)) {
86
            throw MissingTheKey::inTheInput($data, $this, $this->key());
87
        }
88
        try {
89
            $objects = [];
90
            foreach ($data[$this->key()] as $objectData) {
91
                $objects[] = $this->item->fromArray($objectData);
92
            }
93
        } catch (Throwable $exception) {
94
            throw CollectionMappingFailed::tryingToMapItem($this, $exception);
95
        }
96
        try {
97
            return $this->collection->fromArray($objects);
98
        } catch (Throwable $exception) {
99
            throw CollectionMappingFailed::tryingToMapCollection($this, $exception);
100
        }
101
    }
102
}
103