IsolateRegistry::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
c 0
b 0
f 0
rs 9.6666
cc 1
eloc 7
nc 1
nop 2
1
<?php
2
3
namespace Isolate\Framework\UnitOfWork\Object;
4
5
use Isolate\LazyObjects\Proxy\LazyProperty;
6
use Isolate\LazyObjects\WrappedObject;
7
use Isolate\UnitOfWork\Object\PropertyAccessor;
8
use Isolate\UnitOfWork\Object\PropertyCloner;
9
use Isolate\UnitOfWork\Object\Registry;
10
use Isolate\UnitOfWork\Object\SnapshotMaker;
11
use Isolate\Framework\UnitOfWork\LazyObjects\InitializationCallback;
12
13
/**
14
 * @api
15
 */
16
class IsolateRegistry implements Registry
17
{
18
    /**
19
     * @var SnapshotMaker
20
     */
21
    private $snapshotMaker;
22
23
    /**
24
     * @var PropertyCloner
25
     */
26
    private $propertyCloner;
27
28
    /**
29
     * @var PropertyAccessor
30
     */
31
    private $propertyAccessor;
32
33
    /**
34
     * @var array
35
     */
36
    private $objects;
37
38
    /**
39
     * @var array
40
     */
41
    private $snapshots;
42
43
    /**
44
     * @var array
45
     */
46
    private $removed;
47
48
    /**
49
     * @param SnapshotMaker $snapshotMaker
50
     * @param PropertyCloner $propertyCloner
51
     */
52
    public function __construct(SnapshotMaker $snapshotMaker, PropertyCloner $propertyCloner)
53
    {
54
        $this->snapshotMaker = $snapshotMaker;
55
        $this->propertyCloner = $propertyCloner;
56
        $this->propertyAccessor = new PropertyAccessor();
57
        $this->objects = [];
58
        $this->snapshots = [];
59
        $this->removed = [];
60
    }
61
62
    /**
63
     * {@inheritdoc}
64
     */
65
    public function isRegistered($object)
66
    {
67
        $targetObject = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
68
69
        return array_key_exists($this->getId($targetObject), $this->objects);
70
    }
71
72
    /**
73
     * {@inheritdoc}
74
     */
75
    public function register($object)
76
    {
77
        if ($object instanceof WrappedObject) {
78
            $targetObject = $object->getWrappedObject();
79
        } else {
80
            $targetObject = $object;
81
        }
82
83
        $this->objects[$this->getId($targetObject)] = $object;
84
        $this->snapshots[$this->getId($targetObject)] = $this->snapshotMaker->makeSnapshotOf($targetObject);
85
86
        if ($object instanceof WrappedObject) {
87
            $this->setLazyPropertiesCallback($object);
88
        }
89
    }
90
91
    /**
92
     * {@inheritdoc}
93
     */
94
    public function getSnapshot($object)
95
    {
96
        $targetObject = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
97
98
        return $this->snapshots[$this->getId($targetObject)];
99
    }
100
101
    /**
102
     * {@inheritdoc}
103
     */
104
    public function makeNewSnapshots()
105
    {
106
        foreach ($this->objects as $id => $object) {
107
            $targetObject = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
108
109
            $this->snapshots[$id] = $this->snapshotMaker->makeSnapshotOf($targetObject);
110
        }
111
    }
112
113
    /**
114
     * {@inheritdoc}
115
     */
116
    public function isRemoved($object)
117
    {
118
        $targetObject = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
119
120
        return array_key_exists($this->getId($targetObject), $this->removed);
121
    }
122
123
    /**
124
     * {@inheritdoc}
125
     */
126
    public function remove($object)
127
    {
128
        if (!$this->isRegistered($object)) {
129
            $this->register($object);
130
        }
131
132
        $targetObject = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
133
134
        $this->removed[$this->getId($targetObject)] = true;
135
    }
136
137
    /**
138
     * {@inheritdoc}
139
     */
140
    public function cleanRemoved()
141
    {
142
        foreach ($this->removed as $id => $object) {
143
            unset($this->snapshots[$id]);
144
            unset($this->objects[$id]);
145
        }
146
147
        $this->removed = [];
148
    }
149
150
    /**
151
     * {@inheritdoc}
152
     */
153
    public function all()
154
    {
155
        $objects = [];
156
        foreach ($this->objects as $object) {
157
            $objects[] = ($object instanceof WrappedObject) ? $object->getWrappedObject() : $object;
158
        }
159
160
        return $objects;
161
    }
162
163
    /**
164
     * {@inheritdoc}
165
     */
166
    public function reset()
167
    {
168
        $this->removed = [];
169
170
        foreach ($this->snapshots as $id => $objectSnapshot) {
171
            if ($this->objects[$id] instanceof WrappedObject) {
172
                $this->propertyCloner->cloneProperties($this->objects[$id]->getWrappedObject(), $objectSnapshot);
173
            } else {
174
                $this->propertyCloner->cloneProperties($this->objects[$id], $objectSnapshot);
175
            }
176
        }
177
    }
178
179
    /**
180
     * @param WrappedObject $lazyObject
181
     */
182
    private function setLazyPropertiesCallback(WrappedObject $lazyObject)
183
    {
184
        foreach ($lazyObject->getLazyProperties() as $lazyProperty) {
185
            $lazyProperty->setInitializationCallback(new InitializationCallback(
186
                $this->snapshotMaker,
187
                $this->propertyAccessor,
188
                $lazyProperty,
189
                $this->snapshots[$this->getId($lazyObject->getWrappedObject())]
190
            ));
191
        }
192
    }
193
194
    /**
195
     * @param $object
196
     * @return string
197
     */
198
    private function getId($object)
199
    {
200
        return spl_object_hash($object);
201
    }
202
}
203