Code Coverage |
||||||||||
Lines |
Functions and Methods |
Classes and Traits |
||||||||
Total | |
88.89% |
128 / 144 |
|
77.78% |
35 / 45 |
CRAP | |
0.00% |
0 / 1 |
AbstractRecord | |
88.89% |
128 / 144 |
|
77.78% |
35 / 45 |
103.61 | |
0.00% |
0 / 1 |
setTable | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setTableFromClassName | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
setPrefix | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
setPrimaryKeys | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
startTransaction | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
2 | |||
isTransaction | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
commitTransaction | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
rollbackTransaction | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
getTable | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getFullTable | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPrefix | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPrimaryKeys | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getPrimaryValues | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
getRowGateway | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getTableGateway | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
toArray | |
42.86% |
3 / 7 |
|
0.00% |
0 / 1 |
9.66 | |||
count | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getIterator | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getRows | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
rows | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
countRows | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
hasRows | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
setColumns | |
100.00% |
9 / 9 |
|
100.00% |
1 / 1 |
7 | |||
setRows | |
100.00% |
8 / 8 |
|
100.00% |
1 / 1 |
4 | |||
processRows | |
100.00% |
3 / 3 |
|
100.00% |
1 / 1 |
2 | |||
processRow | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
3 | |||
addWith | |
66.67% |
6 / 9 |
|
0.00% |
0 / 1 |
2.15 | |||
hasWith | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
hasWiths | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
getWiths | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getWithRelationships | |
100.00% |
5 / 5 |
|
100.00% |
1 / 1 |
4 | |||
processWithRelationships | |
95.65% |
22 / 23 |
|
0.00% |
0 / 1 |
12 | |||
setRelationship | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
1 | |||
getRelationship | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
hasRelationship | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
getRelationships | |
0.00% |
0 / 1 |
|
0.00% |
0 / 1 |
2 | |||
hasRelationships | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__set | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
__get | |
87.50% |
7 / 8 |
|
0.00% |
0 / 1 |
4.03 | |||
__isset | |
71.43% |
5 / 7 |
|
0.00% |
0 / 1 |
4.37 | |||
__unset | |
100.00% |
2 / 2 |
|
100.00% |
1 / 1 |
2 | |||
offsetExists | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetGet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetSet | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 | |||
offsetUnset | |
100.00% |
1 / 1 |
|
100.00% |
1 / 1 |
1 |
1 | <?php |
2 | /** |
3 | * Pop PHP Framework (http://www.popphp.org/) |
4 | * |
5 | * @link https://github.com/popphp/popphp-framework |
6 | * @author Nick Sagona, III <dev@nolainteractive.com> |
7 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
8 | * @license http://www.popphp.org/license New BSD License |
9 | */ |
10 | |
11 | /** |
12 | * @namespace |
13 | */ |
14 | namespace Pop\Db\Record; |
15 | |
16 | use Pop\Db\Db; |
17 | use Pop\Db\Gateway; |
18 | use Pop\Db\Sql\Parser; |
19 | use ArrayIterator; |
20 | |
21 | /** |
22 | * Abstract record class |
23 | * |
24 | * @category Pop |
25 | * @package Pop\Db |
26 | * @author Nick Sagona, III <dev@nolainteractive.com> |
27 | * @copyright Copyright (c) 2009-2024 NOLA Interactive, LLC. (http://www.nolainteractive.com) |
28 | * @license http://www.popphp.org/license New BSD License |
29 | * @version 6.5.0 |
30 | */ |
31 | abstract class AbstractRecord implements \ArrayAccess, \Countable, \IteratorAggregate |
32 | { |
33 | |
34 | /** |
35 | * Table name |
36 | * @var ?string |
37 | */ |
38 | protected ?string $table = null; |
39 | |
40 | /** |
41 | * Table prefix |
42 | * @var ?string |
43 | */ |
44 | protected ?string $prefix = null; |
45 | |
46 | /** |
47 | * Primary keys |
48 | * @var array |
49 | */ |
50 | protected array $primaryKeys = ['id']; |
51 | |
52 | /** |
53 | * Row gateway |
54 | * @var ?Gateway\Row |
55 | */ |
56 | protected ?Gateway\Row $rowGateway = null; |
57 | |
58 | /** |
59 | * Table gateway |
60 | * @var ?Gateway\Table |
61 | */ |
62 | protected ?Gateway\Table $tableGateway = null; |
63 | |
64 | /** |
65 | * Is new record flag |
66 | * @var bool |
67 | */ |
68 | protected bool $isNew = false; |
69 | |
70 | /** |
71 | * Is transaction flag |
72 | * @var bool |
73 | */ |
74 | protected bool $isTransaction = false; |
75 | |
76 | /** |
77 | * With relationships |
78 | * @var array |
79 | */ |
80 | protected array $with = []; |
81 | |
82 | /** |
83 | * With relationship options |
84 | * @var array |
85 | */ |
86 | protected array $withOptions = []; |
87 | |
88 | /** |
89 | * With relationship children |
90 | * @var ?string |
91 | */ |
92 | protected ?string $withChildren = null; |
93 | |
94 | /** |
95 | * Relationships |
96 | * @var array |
97 | */ |
98 | protected array $relationships = []; |
99 | |
100 | /** |
101 | * Set the table |
102 | * |
103 | * @param string $table |
104 | * @return AbstractRecord |
105 | */ |
106 | public function setTable(string $table): AbstractRecord |
107 | { |
108 | $this->table = $table; |
109 | return $this; |
110 | } |
111 | |
112 | /** |
113 | * Set the table from a class name |
114 | * |
115 | * @param ?string $class |
116 | * @return AbstractRecord |
117 | */ |
118 | public function setTableFromClassName(?string $class = null): AbstractRecord |
119 | { |
120 | if ($class === null) { |
121 | $class = get_class($this); |
122 | } |
123 | |
124 | if (str_contains($class, '_')) { |
125 | $cls = substr($class, (strrpos($class, '_') + 1)); |
126 | } else if (str_contains($class, '\\')) { |
127 | $cls = substr($class, (strrpos($class, '\\') + 1)); |
128 | } else { |
129 | $cls = $class; |
130 | } |
131 | |
132 | return $this->setTable(Parser\Table::parse($cls)); |
133 | } |
134 | |
135 | /** |
136 | * Set the table prefix |
137 | * |
138 | * @param string $prefix |
139 | * @return AbstractRecord |
140 | */ |
141 | public function setPrefix(string $prefix): AbstractRecord |
142 | { |
143 | $this->prefix = $prefix; |
144 | return $this; |
145 | } |
146 | |
147 | /** |
148 | * Set the primary keys |
149 | * |
150 | * @param array $keys |
151 | * @return AbstractRecord |
152 | */ |
153 | public function setPrimaryKeys(array $keys): AbstractRecord |
154 | { |
155 | $this->primaryKeys = $keys; |
156 | return $this; |
157 | } |
158 | |
159 | /** |
160 | * Start transaction |
161 | * |
162 | * @return AbstractRecord |
163 | */ |
164 | public function startTransaction(): AbstractRecord |
165 | { |
166 | $class = get_called_class(); |
167 | if (Db::hasDb($class)) { |
168 | Db::db($class)->beginTransaction(); |
169 | } |
170 | $this->isTransaction = true; |
171 | return $this; |
172 | } |
173 | |
174 | /** |
175 | * Is transaction |
176 | * |
177 | * @return bool |
178 | */ |
179 | public function isTransaction(): bool |
180 | { |
181 | return $this->isTransaction; |
182 | } |
183 | |
184 | /** |
185 | * Commit transaction |
186 | * |
187 | * @throws \Pop\Db\Exception |
188 | * @return AbstractRecord |
189 | */ |
190 | public function commitTransaction(): AbstractRecord |
191 | { |
192 | $class = get_called_class(); |
193 | if (($this->isTransaction) && (Db::hasDb($class))) { |
194 | Db::db($class)->commit(); |
195 | } |
196 | $this->isTransaction = false; |
197 | return $this; |
198 | } |
199 | |
200 | /** |
201 | * Rollback transaction |
202 | * |
203 | * @throws \Pop\Db\Exception |
204 | * @return AbstractRecord |
205 | */ |
206 | public function rollbackTransaction(): AbstractRecord |
207 | { |
208 | $class = get_called_class(); |
209 | if (($this->isTransaction) && (Db::hasDb($class))) { |
210 | Db::db($class)->rollback(); |
211 | } |
212 | $this->isTransaction = false; |
213 | return $this; |
214 | } |
215 | |
216 | /** |
217 | * Get the table |
218 | * |
219 | * @return ?string |
220 | */ |
221 | public function getTable(): ?string |
222 | { |
223 | return $this->table; |
224 | } |
225 | |
226 | /** |
227 | * Get the full table name (prefix + table) |
228 | * |
229 | * @return string |
230 | */ |
231 | public function getFullTable(): string |
232 | { |
233 | return $this->prefix . $this->table; |
234 | } |
235 | |
236 | /** |
237 | * Get the table prefix |
238 | * |
239 | * @return ?string |
240 | */ |
241 | public function getPrefix(): ?string |
242 | { |
243 | return $this->prefix; |
244 | } |
245 | |
246 | /** |
247 | * Get the primary keys |
248 | * |
249 | * @return array |
250 | */ |
251 | public function getPrimaryKeys(): array |
252 | { |
253 | return $this->primaryKeys; |
254 | } |
255 | |
256 | /** |
257 | * Get the primary values |
258 | * |
259 | * @return array |
260 | */ |
261 | public function getPrimaryValues(): array |
262 | { |
263 | return ($this->rowGateway !== null) ? |
264 | array_intersect_key($this->rowGateway->getColumns(), array_flip($this->primaryKeys)) : []; |
265 | } |
266 | |
267 | /** |
268 | * Get the row gateway |
269 | * |
270 | * @return ?Gateway\Row |
271 | */ |
272 | public function getRowGateway(): ?Gateway\Row |
273 | { |
274 | return $this->rowGateway; |
275 | } |
276 | |
277 | /** |
278 | * Get the table gateway |
279 | * |
280 | * @return ?Gateway\Table |
281 | */ |
282 | public function getTableGateway(): ?Gateway\Table |
283 | { |
284 | return $this->tableGateway; |
285 | } |
286 | |
287 | /** |
288 | * Get column values as array |
289 | * |
290 | * @return array |
291 | */ |
292 | public function toArray(): array |
293 | { |
294 | $columns = $this->rowGateway->getColumns(); |
295 | |
296 | if ($this->hasRelationships()) { |
297 | $relationships = $this->getRelationships(); |
298 | foreach ($relationships as $name => $relationship) { |
299 | $columns[$name] = (is_object($relationship) && method_exists($relationship, 'toArray')) ? |
300 | $relationship->toArray() : $relationship; |
301 | } |
302 | } |
303 | |
304 | return $columns; |
305 | } |
306 | |
307 | /** |
308 | * Method to get count of fields in row gateway |
309 | * |
310 | * @return int |
311 | */ |
312 | public function count(): int |
313 | { |
314 | return $this->rowGateway->count(); |
315 | } |
316 | |
317 | /** |
318 | * Method to iterate over the columns |
319 | * |
320 | * @return ArrayIterator |
321 | */ |
322 | public function getIterator(): ArrayIterator |
323 | { |
324 | return $this->rowGateway->getIterator(); |
325 | } |
326 | |
327 | /** |
328 | * Get the rows |
329 | * |
330 | * @return Collection |
331 | */ |
332 | public function getRows(): Collection |
333 | { |
334 | return new Collection($this->tableGateway->getRows()); |
335 | } |
336 | |
337 | /** |
338 | * Get the rows (alias method) |
339 | * |
340 | * @return Collection |
341 | */ |
342 | public function rows(): Collection |
343 | { |
344 | return $this->getRows(); |
345 | } |
346 | |
347 | /** |
348 | * Get the count of rows returned in the result |
349 | * |
350 | * @return int |
351 | */ |
352 | public function countRows(): int |
353 | { |
354 | return $this->tableGateway->getNumberOfRows(); |
355 | } |
356 | |
357 | /** |
358 | * Determine if the result has rows |
359 | * |
360 | * @return bool |
361 | */ |
362 | public function hasRows(): bool |
363 | { |
364 | return ($this->tableGateway->getNumberOfRows() > 0); |
365 | } |
366 | |
367 | /** |
368 | * Set all the table column values at once |
369 | * |
370 | * @param mixed $columns |
371 | * @throws Exception |
372 | * @return AbstractRecord |
373 | */ |
374 | public function setColumns(mixed $columns = null): AbstractRecord |
375 | { |
376 | if ($columns !== null) { |
377 | if (is_array($columns) || ($columns instanceof \ArrayObject)) { |
378 | $this->rowGateway->setColumns((array)$columns); |
379 | } else if ($columns instanceof AbstractRecord) { |
380 | $this->rowGateway->setColumns($columns->toArray()); |
381 | } else if (($columns instanceof \ArrayAccess) && method_exists($columns, 'toArray')) { |
382 | $this->rowGateway->setColumns($columns->toArray()); |
383 | } else { |
384 | throw new Exception('The parameter passed must be an arrayable object.'); |
385 | } |
386 | } |
387 | |
388 | return $this; |
389 | } |
390 | |
391 | /** |
392 | * Set all the table rows at once |
393 | * |
394 | * @param ?array $rows |
395 | * @param bool $toArray |
396 | * @return AbstractRecord |
397 | */ |
398 | public function setRows(array $rows = null, bool|array $toArray = false): AbstractRecord |
399 | { |
400 | $this->rowGateway->setColumns(); |
401 | $this->tableGateway->setRows(); |
402 | |
403 | if ($rows !== null) { |
404 | $this->rowGateway->setColumns(((isset($rows[0])) ? (array)$rows[0] : [])); |
405 | foreach ($rows as $i => $row) { |
406 | $rows[$i] = $this->processRow($row, $toArray); |
407 | } |
408 | $this->tableGateway->setRows($rows); |
409 | } |
410 | |
411 | return $this; |
412 | } |
413 | |
414 | /** |
415 | * Process table rows |
416 | * |
417 | * @param array $rows |
418 | * @param bool $toArray |
419 | * @return array |
420 | */ |
421 | public function processRows(array $rows, bool|array $toArray = false): array |
422 | { |
423 | foreach ($rows as $i => $row) { |
424 | $rows[$i] = $this->processRow($row, $toArray); |
425 | } |
426 | return $rows; |
427 | } |
428 | |
429 | /** |
430 | * Process a table row |
431 | * |
432 | * @param array $row |
433 | * @param bool $toArray |
434 | * @return mixed |
435 | */ |
436 | public function processRow(array $row, bool|array $toArray = false): mixed |
437 | { |
438 | if ($toArray !== false) { |
439 | return (is_array($toArray)) ? (new Collection($row))->toArray($toArray): $row; |
440 | } else { |
441 | $record = new static(); |
442 | $record->setColumns($row); |
443 | return $record; |
444 | } |
445 | } |
446 | |
447 | /** |
448 | * Set with relationships |
449 | * |
450 | * @param string $name |
451 | * @param ?array $options |
452 | * @return AbstractRecord |
453 | */ |
454 | public function addWith(string $name, array $options = null): AbstractRecord |
455 | { |
456 | $children = null; |
457 | if (str_contains($name, '.')) { |
458 | $names = explode('.', $name); |
459 | $name = array_shift($names); |
460 | $children = implode('.', $names); |
461 | } |
462 | $this->with[] = $name; |
463 | $this->withOptions[] = $options; |
464 | $this->withChildren = $children; |
465 | |
466 | return $this; |
467 | } |
468 | |
469 | /** |
470 | * Determine if there is specific with relationship |
471 | * |
472 | * @param string $name |
473 | * @return bool |
474 | */ |
475 | public function hasWith(string $name): bool |
476 | { |
477 | return (isset($this->with[$name])); |
478 | } |
479 | |
480 | /** |
481 | * Determine if there are with relationships |
482 | * |
483 | * @return bool |
484 | */ |
485 | public function hasWiths(): bool |
486 | { |
487 | return (count($this->with) > 0); |
488 | } |
489 | |
490 | /** |
491 | * Get with relationships |
492 | * |
493 | * @return array |
494 | */ |
495 | public function getWiths(): array |
496 | { |
497 | return $this->with; |
498 | } |
499 | |
500 | /** |
501 | * Get with relationships |
502 | * |
503 | * @param bool $eager |
504 | * @return AbstractRecord |
505 | */ |
506 | public function getWithRelationships(bool $eager = true): AbstractRecord |
507 | { |
508 | foreach ($this->with as $i => $name) { |
509 | $options = (isset($this->withOptions[$i])) ? $this->withOptions[$i] : null; |
510 | |
511 | if (method_exists($this, $name)) { |
512 | $this->relationships[$name] = $this->{$name}($options, $eager); |
513 | } |
514 | } |
515 | |
516 | return $this; |
517 | } |
518 | |
519 | /** |
520 | * Process with relationships |
521 | * |
522 | * @param array $rows |
523 | * @return AbstractRecord |
524 | */ |
525 | public function processWithRelationships(array $rows): AbstractRecord |
526 | { |
527 | foreach ($this->relationships as $name => $relationship) { |
528 | $withIds = []; |
529 | if ($relationship instanceof \Pop\Db\Record\Relationships\HasOneOf) { |
530 | $primaryKey = $relationship->getForeignKey(); |
531 | foreach ($rows as $i => $row) { |
532 | if (isset($row[$primaryKey]) && !in_array($row[$primaryKey], $withIds)) { |
533 | $withIds[] = $row[$primaryKey]; |
534 | } |
535 | } |
536 | $results = $relationship->getEagerRelationships($withIds); |
537 | } else { |
538 | $primaryKey = $this->getPrimaryKeys(); |
539 | if (count($primaryKey) == 1) { |
540 | $primaryKey = reset($primaryKey); |
541 | } |
542 | foreach ($rows as $i => $row) { |
543 | $primaryValues = $rows[$i]->getPrimaryValues(); |
544 | if (count($primaryValues) == 1) { |
545 | $withId = reset($primaryValues); |
546 | if (!in_array($withId, $withIds)) { |
547 | $withIds[] = $withId; |
548 | } |
549 | } |
550 | } |
551 | $results = $relationship->getEagerRelationships($withIds); |
552 | } |
553 | foreach ($rows as $i => $row) { |
554 | if (isset($results[$row[$primaryKey]])) { |
555 | $row->setRelationship($name, $results[$row[$primaryKey]]); |
556 | } else { |
557 | $row->setRelationship($name, []); |
558 | } |
559 | } |
560 | } |
561 | |
562 | return $this; |
563 | } |
564 | |
565 | /** |
566 | * Set relationship |
567 | * |
568 | * @param string $name |
569 | * @param mixed $relationship |
570 | * @return AbstractRecord |
571 | */ |
572 | public function setRelationship(string $name, mixed $relationship): AbstractRecord |
573 | { |
574 | $this->relationships[$name] = $relationship; |
575 | return $this; |
576 | } |
577 | |
578 | /** |
579 | * Get relationship |
580 | * |
581 | * @param string $name |
582 | * @return mixed |
583 | */ |
584 | public function getRelationship(string $name): mixed |
585 | { |
586 | return $this->relationships[$name] ?? null; |
587 | } |
588 | |
589 | /** |
590 | * Has relationship |
591 | * |
592 | * @param string $name |
593 | * @return bool |
594 | */ |
595 | public function hasRelationship(string $name): bool |
596 | { |
597 | return (isset($this->relationships[$name])); |
598 | } |
599 | |
600 | /** |
601 | * Get relationships |
602 | * |
603 | * @return array |
604 | */ |
605 | public function getRelationships(): array |
606 | { |
607 | return $this->relationships; |
608 | } |
609 | |
610 | /** |
611 | * Get relationships |
612 | * |
613 | * @return bool |
614 | */ |
615 | public function hasRelationships(): bool |
616 | { |
617 | return (count($this->relationships) > 0); |
618 | } |
619 | |
620 | /** |
621 | * Magic method to set the property to the value of $this->rowGateway[$name] |
622 | * |
623 | * @param string $name |
624 | * @param mixed $value |
625 | * @return void |
626 | */ |
627 | public function __set(string $name, mixed $value) |
628 | { |
629 | $this->rowGateway[$name] = $value; |
630 | } |
631 | |
632 | /** |
633 | * Magic method to return the value of $this->rowGateway[$name] |
634 | * |
635 | * @param string $name |
636 | * @return mixed |
637 | */ |
638 | public function __get(string $name): mixed |
639 | { |
640 | $result = null; |
641 | |
642 | if (isset($this->relationships[$name])) { |
643 | $result = $this->relationships[$name]; |
644 | } else if (isset($this->rowGateway[$name])) { |
645 | $result = $this->rowGateway[$name]; |
646 | } else if (method_exists($this, $name)) { |
647 | $result = $this->{$name}(); |
648 | } |
649 | |
650 | return $result; |
651 | } |
652 | |
653 | /** |
654 | * Magic method to return the isset value of $this->rowGateway[$name] |
655 | * |
656 | * @param string $name |
657 | * @return bool |
658 | */ |
659 | public function __isset(string $name): bool |
660 | { |
661 | if (isset($this->relationships[$name])) { |
662 | return true; |
663 | } else if (isset($this->rowGateway[$name])) { |
664 | return true; |
665 | } else if (method_exists($this, $name)) { |
666 | return true; |
667 | } else { |
668 | return false; |
669 | } |
670 | } |
671 | |
672 | /** |
673 | * Magic method to unset $this->rowGateway[$name] |
674 | * |
675 | * @param string $name |
676 | * @return void |
677 | */ |
678 | public function __unset(string $name): void |
679 | { |
680 | if (isset($this->rowGateway[$name])) { |
681 | unset($this->rowGateway[$name]); |
682 | } |
683 | } |
684 | |
685 | /** |
686 | * ArrayAccess offsetExists |
687 | * |
688 | * @param mixed $offset |
689 | * @return bool |
690 | */ |
691 | public function offsetExists(mixed $offset): bool |
692 | { |
693 | return $this->__isset($offset); |
694 | } |
695 | |
696 | /** |
697 | * ArrayAccess offsetGet |
698 | * |
699 | * @param mixed $offset |
700 | * @return mixed |
701 | */ |
702 | public function offsetGet(mixed $offset): mixed |
703 | { |
704 | return $this->__get($offset); |
705 | } |
706 | |
707 | /** |
708 | * ArrayAccess offsetSet |
709 | * |
710 | * @param mixed $offset |
711 | * @param mixed $value |
712 | * @return void |
713 | */ |
714 | public function offsetSet(mixed $offset, mixed $value): void |
715 | { |
716 | $this->__set($offset, $value); |
717 | } |
718 | |
719 | /** |
720 | * ArrayAccess offsetUnset |
721 | * |
722 | * @param mixed $offset |
723 | * @return void |
724 | */ |
725 | public function offsetUnset(mixed $offset): void |
726 | { |
727 | $this->__unset($offset); |
728 | } |
729 | |
730 | } |