Passed
Push — master ( 755d71...a4e23e )
by Anton
03:40 queued 01:48
created

State::getStorage()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Importance

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