AbstractDto   A
last analyzed

Complexity

Total Complexity 10

Size/Duplication

Total Lines 84
Duplicated Lines 0 %

Test Coverage

Coverage 95.83%

Importance

Changes 5
Bugs 0 Features 0
Metric Value
eloc 17
c 5
b 0
f 0
dl 0
loc 84
ccs 23
cts 24
cp 0.9583
rs 10
wmc 10

7 Methods

Rating   Name   Duplication   Size   Complexity  
A getAttributeMetadata() 0 5 1
A offsetGet() 0 3 1
A getIterator() 0 5 2
A executeMethod() 0 10 2
A offsetSet() 0 7 2
A offsetUnset() 0 3 1
A offsetExists() 0 3 1
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 *  This file is part of the Micro framework package.
7
 *
8
 *  (c) Stanislau Komar <[email protected]>
9
 *
10
 *  For the full copyright and license information, please view the LICENSE
11
 *  file that was distributed with this source code.
12
 */
13
14
namespace Micro\Library\DTO\Object;
15
16
use ArrayAccess;
17
use IteratorAggregate;
18
19
/**
20
 * @template-implements ArrayAccess<string, mixed>
21
 * @template-implements IteratorAggregate<string, mixed>
22
 */
23
abstract class AbstractDto implements \ArrayAccess, \IteratorAggregate
24
{
25
    /**
26
     * {@inheritDoc}
27
     */
28 1
    public function offsetExists(mixed $offset): bool
29
    {
30 1
        return (bool) $this->getAttributeMetadata($offset);
31
    }
32
33
    /**
34
     * {@inheritDoc}
35
     */
36 9
    public function offsetGet(mixed $offset): mixed
37
    {
38 9
        return $this->executeMethod('get', $offset, null);
39
    }
40
41
    /**
42
     * {@inheritDoc}
43
     */
44 5
    public function offsetSet(mixed $offset, mixed $value): void
45
    {
46 5
        if (!$offset) {
47
            throw new \InvalidArgumentException();
48
        }
49
50 5
        $this->executeMethod('set', $offset, $value);
51
    }
52
53
    /**
54
     * {@inheritDoc}
55
     */
56 1
    public function offsetUnset(mixed $offset): void
57
    {
58 1
        $this->offsetSet($offset, null);
59
    }
60
61
    /**
62
     * @return \Traversable<string, mixed>
63
     */
64 4
    public function getIterator(): \Traversable
65
    {
66 4
        return (function () {
67 4
            foreach ($this->attributesMetadata() as $attributeName => $meta) {
68 4
                yield $attributeName => $this->offsetGet($attributeName);
69
            }
70 4
        })();
71
    }
72
73
    /**
74
     * @return array<string, mixed>
75
     */
76
    abstract protected static function attributesMetadata(): array;
77
78
    /**
79
     * @param string $attribute
80
     *
81
     * @return mixed[]|null
82
     */
83 10
    protected function getAttributeMetadata(string $attribute): ?array
84
    {
85 10
        $meta = static::attributesMetadata();
86
87 10
        return $meta[$attribute] ?? null;
88
    }
89
90
    /**
91
     * @param string $method
92
     * @param string $property
93
     * @param mixed  $value
94
     *
95
     * @return mixed
96
     */
97 10
    protected function executeMethod(string $method, string $property, mixed $value): mixed
98
    {
99 10
        $meta = $this->getAttributeMetadata($property);
100 10
        if (!$meta) {
101 1
            throw new \InvalidArgumentException(sprintf('Property "%s" is not declared in the class "%s".', $property, static::class));
102
        }
103
104 10
        $actionName = $meta['actionName'];
105
106 10
        return $this->{$method.$actionName}($value);
107
    }
108
}
109