Passed
Push — master ( 2b47f2...d0c705 )
by Jesse
02:10
created

Result::__construct()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 6
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 2
1
<?php
2
declare(strict_types=1);
3
4
namespace Stratadox\TableLoader;
5
6
use ArrayIterator;
7
use BadMethodCallException;
8
use Exception;
9
use Stratadox\IdentityMap\IdentityMap;
10
use Stratadox\IdentityMap\MapsObjectsByIdentity;
11
use Traversable;
12
13
final class Result implements ContainsResultingObjects
14
{
15
    private $objects;
16
    private $identityMap;
17
18
    private function __construct(
19
        array $objects,
20
        MapsObjectsByIdentity $identityMap
21
    ) {
22
        $this->objects = $objects;
23
        $this->identityMap = $identityMap;
24
    }
25
26
    /**
27
     * Makes a new result from an array of objects as produced by table loaders
28
     * and an identity map.
29
     *
30
     * @param array[]               $objects     Array of objects, as:
31
     *                                           [label => [id => object]]
32
     * @param MapsObjectsByIdentity $identityMap The map of objects by class and
33
     *                                           identifier.
34
     * @return ContainsResultingObjects
35
     */
36
    public static function fromArray(
37
        array $objects,
38
        MapsObjectsByIdentity $identityMap = null
39
    ): ContainsResultingObjects {
40
        return new self($objects, $identityMap ?: IdentityMap::startEmpty());
41
    }
42
43
    /** @inheritdoc */
44
    public function has(string $class, string $id): bool
45
    {
46
        return $this->identityMap->has($class, $id);
47
    }
48
49
    /** @inheritdoc */
50
    public function get(string $class, string $id): object
51
    {
52
        return $this->identityMap->get($class, $id);
53
    }
54
55
    /** @inheritdoc */
56
    public function add(
57
        string $label,
58
        string $idForLoading,
59
        string $idForMap,
60
        object $object
61
    ): ContainsResultingObjects {
62
        return new self($this->merge(
63
            $this->objects,
64
            [$label => [$idForLoading => $object]]
65
        ), $this->identityMap->add($idForMap, $object));
66
    }
67
68
    /** @inheritdoc */
69
    public function mergeWith(
70
        ContainsResultingObjects $otherObjects
71
    ): ContainsResultingObjects {
72
        return new self(
73
            $this->merge($this->objects, $otherObjects),
74
            $otherObjects->identityMap()
75
        );
76
    }
77
78
    /** @inheritdoc */
79
    public function include(
80
        string $label,
81
        string $id,
82
        object $object
83
    ): ContainsResultingObjects {
84
        return new self($this->merge(
85
            $this->objects,
86
            [$label => [$id => $object]]
87
        ), $this->identityMap);
88
    }
89
90
    /**
91
     * @param object[][] $result
92
     * @param object[][] $with
93
     * @return array
94
     */
95
    private function merge(iterable $result, iterable $with): array
96
    {
97
        foreach ($with as $label => $objects) {
98
            foreach ($objects as $id => $object) {
99
                $result[$label][$id] = $object;
100
            }
101
        }
102
        return $result;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $result returns the type iterable which is incompatible with the type-hinted return array.
Loading history...
103
    }
104
105
    /** @inheritdoc */
106
    public function identityMap(): MapsObjectsByIdentity
107
    {
108
        return $this->identityMap;
109
    }
110
111
    /** @inheritdoc */
112
    public function getIterator(): Traversable
113
    {
114
        return new ArrayIterator($this->objects);
115
    }
116
117
    /** @inheritdoc */
118
    public function offsetExists($offset): bool
119
    {
120
        return isset($this->objects[$offset]);
121
    }
122
123
    /** @inheritdoc */
124
    public function offsetGet($offset): array
125
    {
126
        return $this->objects[$offset];
127
    }
128
129
    /**
130
     * @inheritdoc
131
     * @throws Exception
132
     */
133
    public function offsetSet($offset, $value): void
134
    {
135
        throw new BadMethodCallException('Altering the results is not allowed.');
136
    }
137
138
    /**
139
     * @inheritdoc
140
     * @throws Exception
141
     */
142
    public function offsetUnset($offset): void
143
    {
144
        throw new BadMethodCallException('Altering the results is not allowed.');
145
    }
146
}
147