Passed
Push — master ( 61bbc0...3efc91 )
by Anton
02:31
created

State::setData()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 4
nc 3
nop 1
dl 0
loc 8
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * Cycle DataMapper ORM
5
 *
6
 * @license   MIT
7
 * @author    Anton Titov (Wolfy-J)
8
 */
9
10
declare(strict_types=1);
11
12
namespace Cycle\ORM\Heap;
13
14
use Cycle\ORM\Command\ContextCarrierInterface;
15
use Cycle\ORM\Context\ConsumerInterface;
16
use Cycle\ORM\Context\ProducerInterface;
17
use Cycle\ORM\Heap\Traits\ClaimTrait;
18
use Cycle\ORM\Heap\Traits\RelationTrait;
19
use Cycle\ORM\Heap\Traits\VisitorTrait;
20
21
/**
22
 * Current node state.
23
 */
24
final class State implements ConsumerInterface, ProducerInterface
25
{
26
    use RelationTrait;
27
    use ClaimTrait;
28
    use VisitorTrait;
29
30
    /** @var int */
31
    private $state;
32
33
    /** @var array */
34
    private $data;
35
36
    /** @var array */
37
    private $transactionData = [];
38
39
    /** @var null|ContextCarrierInterface */
40
    private $command;
41
42
    /** @var ContextCarrierInterface[] */
43
    private $consumers;
44
45
    /** @var \SplObjectStorage[] */
46
    private $storage = [];
47
48
    /**
49
     * @param int   $state
50
     * @param array $data
51
     */
52
    public function __construct(int $state, array $data)
53
    {
54
        $this->state = $state;
55
        $this->data = $data;
56
        $this->transactionData = $data;
57
    }
58
59
    /**
60
     * Set new state value.
61
     *
62
     * @param int $state
63
     */
64
    public function setStatus(int $state): void
65
    {
66
        $this->state = $state;
67
    }
68
69
    /**
70
     * Get current state.
71
     *
72
     * @return int
73
     */
74
    public function getStatus(): int
75
    {
76
        return $this->state;
77
    }
78
79
    /**
80
     * Set new state data (will trigger state handlers).
81
     *
82
     * @param array $data
83
     */
84
    public function setData(array $data): void
85
    {
86
        if ($data === []) {
87
            return;
88
        }
89
90
        foreach ($data as $column => $value) {
91
            $this->register($column, $value);
92
        }
93
    }
94
95
    /**
96
     * Get current state data.
97
     *
98
     * @return array
99
     */
100
    public function getData(): array
101
    {
102
        return $this->data;
103
    }
104
105
    /**
106
     * Get current state data.
107
     *
108
     * @return array
109
     */
110
    public function getTransactionData(): array
111
    {
112
        return $this->transactionData;
113
    }
114
115
    /**
116
     * Set the reference to the object creation command (non executed).
117
     *
118
     * @param ContextCarrierInterface|null $cmd
119
     * @internal
120
     */
121
    public function setCommand(ContextCarrierInterface $cmd = null): void
122
    {
123
        $this->command = $cmd;
124
    }
125
126
    /**
127
     * @return null|ContextCarrierInterface
128
     * @internal
129
     */
130
    public function getCommand(): ?ContextCarrierInterface
131
    {
132
        return $this->command;
133
    }
134
135
    /**
136
     * Storage to store temporary cross entity links.
137
     *
138
     * @param string $type
139
     * @return \SplObjectStorage
140
     * @internal
141
     */
142
    public function getStorage(string $type): \SplObjectStorage
143
    {
144
        if (!isset($this->storage[$type])) {
145
            $this->storage[$type] = new \SplObjectStorage();
146
        }
147
148
        return $this->storage[$type];
149
    }
150
151
    /**
152
     * @inheritdoc
153
     */
154
    public function forward(
155
        string $key,
156
        ConsumerInterface $consumer,
157
        string $target,
158
        bool $trigger = false,
159
        int $stream = ConsumerInterface::DATA
160
    ): void {
161
        $this->consumers[$key][] = [$consumer, $target, $stream];
162
163
        if ($trigger || !empty($this->data[$key])) {
164
            $this->register($key, $this->data[$key] ?? null, false, $stream);
165
        }
166
    }
167
168
    /**
169
     * @inheritdoc
170
     */
171
    public function register(
172
        string $key,
173
        $value,
174
        bool $fresh = false,
175
        int $stream = self::DATA
176
    ): void {
177
        if (!$fresh) {
178
            // custom, non value objects can be supported here
179
            $fresh = ($this->data[$key] ?? null) != $value;
180
        }
181
182
        if (!array_key_exists($key, $this->transactionData)) {
183
            $this->transactionData[$key] = $value;
184
        }
185
186
        $this->data[$key] = $value;
187
188
        // cascade
189
        if (!empty($this->consumers[$key])) {
190
            foreach ($this->consumers[$key] as $id => $consumer) {
191
                /** @var ConsumerInterface $acc */
192
                $acc = $consumer[0];
193
                $acc->register($consumer[1], $value, $fresh, $consumer[2]);
194
                $fresh = false;
195
            }
196
        }
197
    }
198
}
199