Completed
Push — master ( fbe2cf...425095 )
by Samuel
11:56
created

ActiveRow::setReferencingRecord()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace SimpleMapper;
6
7
use Nette\Database\Table\Selection as NetteDatabaseSelection;
8
use Nette\Database\Table\ActiveRow as NetteDatabaseActiveRow;
9
use ArrayIterator;
10
use IteratorAggregate;
11
use Nette\Database\Table\IRow;
12
use Nette\DeprecatedException;
13
use SimpleMapper\Exception\ActiveRowException;
14
use SimpleMapper\Structure\Structure;
15
16
class ActiveRow implements IteratorAggregate, IRow
17
{
18
    /** @var NetteDatabaseActiveRow */
19
    protected $record;
20
21
    /** @var Structure */
22
    protected $structure;
23
24 38
    /** @var ActiveRow|null */
25
    protected $referencingRecord;
26 38
27 38
    /**
28 38
     * @param NetteDatabaseActiveRow $record
29
     * @param Structure $structure
30
     */
31
    public function __construct(NetteDatabaseActiveRow $record, Structure $structure)
32
    {
33
        $this->record = $record;
34 16
        $this->structure = $structure;
35
    }
36 16
37 14
    /**
38
     * @param string $name
39
     * @return mixed|ActiveRow
40
     */
41
    public function __get($name)
42
    {
43
        $result = $this->record->$name;
44
        return $result instanceof IRow ? $this->prepareRecord($result) : $result;
45
    }
46
47
    /**
48
     * @return NetteDatabaseActiveRow
49
     */
50
    public function getRecord(): NetteDatabaseActiveRow
51
    {
52
        return $this->record;
53
    }
54
55
    /**
56
     * @return NetteDatabaseSelection
57
     */
58
    public function getTable(): NetteDatabaseSelection
59
    {
60
        return $this->record->getTable();
61
    }
62
63
    /**
64
     * @param NetteDatabaseSelection $selection
65
     * @throws ActiveRowException
66
     */
67
    public function setTable(NetteDatabaseSelection $selection): void
68
    {
69
        throw new ActiveRowException('Internal IRow interface method');
70
    }
71
72
    /**********************************************************************\
73
     * Wrapper function
74
    \**********************************************************************/
75
76
    /**
77
     * @return string
78
     */
79 6
    public function __toString(): string
80
    {
81 6
        return (string) $this->record;
82
    }
83
84
    /**
85
     * @return array
86
     */
87
    public function toArray(): array
88 2
    {
89
        return $this->record->toArray();
90 2
    }
91
92
    /**
93
     * @param bool|true $need
94
     * @return mixed
95
     */
96
    public function getPrimary($need = true)
97 2
    {
98
        return $this->record->getPrimary($need);
99 2
    }
100
101
    /**
102
     * @param bool|true $need
103
     * @return string
104
     */
105
    public function getSignature($need = true): string
106 2
    {
107
        return $this->record->getSignature($need);
108 2
    }
109
110
    /**
111
     * @param array|\Traversable $data
112
     * @return bool
113
     */
114 2
    public function update($data): bool
115
    {
116 2
        return $this->record->update($data);
117
    }
118
119
    /**
120
     * @return int
121
     */
122
    public function delete(): int
123
    {
124
        return $this->record->delete();
125 6
    }
126
127 6
    /**
128 6
     * Returns referenced row
129
     * @param string $key
130
     * @param string $throughColumn
131
     * @return ActiveRow|null
132
     */
133
    public function ref($key, $throughColumn = null): ?ActiveRow
134
    {
135
        $row = $this->record->ref($key, $throughColumn);
136
        if($row instanceof IRow) {
137
            $result = $this->prepareRecord($row);
138 4
            $result->setReferencingRecord($this);
139
            return $result;
140 4
        }
141 4
142
        return null;
143
    }
144
145
    /**
146
     * Returns referencing rows
147
     * @param string $key
148
     * @param string $throughColumn
149
     * @return Selection
150
     */
151 4
    public function related($key, $throughColumn = null): ?Selection
152
    {
153 4
        $selection = $this->record->related($key, $throughColumn);
154
        return $selection instanceof NetteDatabaseSelection ? $this->prepareSelection($selection) : null;
155
    }
156
157
    /**********************************************************************\
158
     * IteratorAggregate interface
159
    \**********************************************************************/
160
161
    /**
162
     * @return ArrayIterator
163
     */
164
    public function getIterator(): ArrayIterator
165 2
    {
166
        return $this->record->getIterator();
167 2
    }
168
169
    /**********************************************************************\
170
     * ArrayAccess interface
171
    \**********************************************************************/
172
173
    /**
174
     * Returns value of column
175 2
     * @param string $key  column name
176
     * @return mixed
177 2
     */
178
    public function offsetGet($key)
179
    {
180
        $result = $this->record->offsetGet($key);
181
        return $result instanceof IRow ? $this->prepareRecord($result) : $result;
182
    }
183
184
    /**
185
     * Tests if column exists
186 2
     * @param string $key   column name
187
     * @return bool
188 2
     */
189
    public function offsetExists($key): bool
190
    {
191
        return $this->record->offsetExists($key);
192
    }
193
194
    /**
195
     * Stores value in column
196 2
     * @param string $key   column name
197
     * @param string $value
198 2
     * @throws DeprecatedException
199
     */
200
    public function offsetSet($key, $value): void
201
    {
202
        $this->record->offsetSet($key, $value);
203
    }
204
205
    /**
206
     * Removes column from data
207
     * @param string $key column name
208
     * @throws DeprecatedException
209
     */
210
    public function offsetUnset($key): void
211
    {
212 4
        $this->record->offsetUnset($key);
213
    }
214 4
215 4
    /**********************************************************************\
216 4
     * Extend methods
217 2
    \**********************************************************************/
218 4
219
    /**
220
     * @param ActiveRow $row
221
     */
222
    public function setReferencingRecord(ActiveRow $row): void
223
    {
224
        $this->referencingRecord = $row;
225
    }
226
227
    /**
228
     * @return null|ActiveRow
229
     */
230 8
    public function getReferencingRecord(): ?ActiveRow
231
    {
232 8
        return $this->referencingRecord;
233 8
    }
234
235
    /**
236
     * Returns mm referencing rows
237
     * @param Selection $selection
238
     * @param string $ref
239
     * @param string $refPrimary
240
     * @return array
241 4
     */
242
    protected function mmRelated(Selection $selection, string $ref, string $refPrimary = 'id'): array
243 4
    {
244 4
        $result = [];
245
        foreach ($selection as $row) {
246
            $result[$row->ref($ref)->$refPrimary] = $row->ref($ref);
247
        }
248
        return $result;
249
    }
250
251
    /**********************************************************************\
252
     * Build methods
253
    \**********************************************************************/
254
255
    /**
256
     * Prepare one record
257
     * @param IRow $row
258
     * @return ActiveRow
259
     */
260
    protected function prepareRecord(IRow $row): ActiveRow
261
    {
262
        $recordClass = $this->structure->getActiveRowClass($row->getTable()->getName());
263
        return new $recordClass($row, $this->structure);
264
    }
265
266
    /**
267
     * Prepare selection
268
     * @param NetteDatabaseSelection $selection
269
     * @return Selection
270
     */
271
    protected function prepareSelection(NetteDatabaseSelection $selection): Selection
272
    {
273
        $selectionClass = $this->structure->getSelectionClass($selection->getName());
274
        return new $selectionClass($selection, $this->structure);
275
    }
276
}
277