HasProperties   A
last analyzed

Complexity

Total Complexity 15

Size/Duplication

Total Lines 140
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 2
Bugs 0 Features 0
Metric Value
eloc 34
dl 0
loc 140
ccs 39
cts 39
cp 1
rs 10
c 2
b 0
f 0
wmc 15

8 Methods

Rating   Name   Duplication   Size   Complexity  
A setPropertyValueOrMap() 0 17 3
A getProperty() 0 18 4
A getProperties() 0 3 1
A getPropertyNames() 0 3 1
A hasProperty() 0 6 2
A getPropertiesMap() 0 3 1
A mapData() 0 5 1
A resolveNestedValue() 0 9 2
1
<?php
2
3
namespace Cerbero\Dto\Traits;
4
5
use Cerbero\Dto\DtoPropertiesMapper;
6
use Cerbero\Dto\DtoProperty;
7
use Cerbero\Dto\Exceptions\UnknownDtoPropertyException;
8
9
/**
10
 * Trait to interact with properties.
11
 *
12
 */
13
trait HasProperties
14
{
15
    /**
16
     * The properties map.
17
     *
18
     * @var array
19
     */
20
    protected $propertiesMap;
21
22
    /**
23
     * Retrieve the DTO properties map
24
     *
25
     * @return array
26
     */
27 32
    public function getPropertiesMap(): array
28
    {
29 32
        return $this->propertiesMap;
30
    }
31
32
    /**
33
     * Retrieve the DTO property names
34
     *
35
     * @return array
36
     */
37 6
    public function getPropertyNames(): array
38
    {
39 6
        return array_keys($this->getPropertiesMap());
40
    }
41
42
    /**
43
     * Retrieve the DTO properties
44
     *
45
     * @return DtoProperty[]
46
     */
47 2
    public function getProperties(): array
48
    {
49 2
        return array_values($this->getPropertiesMap());
50
    }
51
52
    /**
53
     * Determine whether the given property is set (even if its value is NULL)
54
     *
55
     * @param string $property
56
     * @return bool
57
     */
58 23
    public function hasProperty(string $property): bool
59
    {
60
        try {
61 23
            return !!$this->getProperty($property);
62 15
        } catch (UnknownDtoPropertyException $e) {
63 15
            return false;
64
        }
65
    }
66
67
    /**
68
     * Retrieve the given DTO property (support dot notation)
69
     *
70
     * @param string $property
71
     * @return DtoProperty
72
     * @throws UnknownDtoPropertyException
73
     */
74 43
    public function getProperty(string $property): DtoProperty
75
    {
76 43
        if (isset($this->propertiesMap[$property])) {
77 28
            return $this->propertiesMap[$property];
78
        }
79
80 26
        if (strpos($property, '.') === false) {
81 24
            throw new UnknownDtoPropertyException(static::class, $property);
82
        }
83
84 8
        [$property, $nestedProperty] = explode('.', $property, 2);
85 8
        $presumedDto = $this->get($property);
0 ignored issues
show
Bug introduced by
It seems like get() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

85
        /** @scrutinizer ignore-call */ 
86
        $presumedDto = $this->get($property);
Loading history...
86
87 7
        if ($presumedDto instanceof self) {
88 6
            return $presumedDto->getProperty($nestedProperty);
89
        }
90
91 1
        throw new UnknownDtoPropertyException(static::class, $nestedProperty);
92
    }
93
94
    /**
95
     * Retrieve the given DTO property or map it if not mapped yet
96
     *
97
     * @param string $property
98
     * @param mixed $value
99
     * @return void
100
     */
101 14
    protected function setPropertyValueOrMap(string $property, $value): void
102
    {
103 14
        if ($this->hasProperty($property)) {
104 7
            $this->getProperty($property)->setValue($value, $this->getFlags());
0 ignored issues
show
Bug introduced by
It seems like getFlags() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

104
            $this->getProperty($property)->setValue($value, $this->/** @scrutinizer ignore-call */ getFlags());
Loading history...
105 7
            return;
106
        }
107
108 7
        $data = $this->toArray();
0 ignored issues
show
Bug introduced by
It seems like toArray() must be provided by classes using this trait. How about adding it as abstract method to this trait? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

108
        /** @scrutinizer ignore-call */ 
109
        $data = $this->toArray();
Loading history...
109
110 7
        if (strpos($property, '.') === false) {
111 5
            $data[$property] = $value;
112
        } else {
113 2
            [$property, $nestedProperty] = explode('.', $property, 2);
114 2
            $data[$property] = $this->resolveNestedValue($nestedProperty, $value);
115
        }
116
117 7
        $this->propertiesMap = $this->mapData($data);
118 6
    }
119
120
    /**
121
     * Retrieve the DTO mapped properties for the given data
122
     *
123
     * @param array $data
124
     * @return array
125
     * @throws \Cerbero\Dto\Exceptions\DtoNotFoundException
126
     * @throws \Cerbero\Dto\Exceptions\MissingValueException
127
     * @throws \Cerbero\Dto\Exceptions\UnexpectedValueException
128
     * @throws UnknownDtoPropertyException
129
     */
130 81
    protected function mapData(array $data): array
131
    {
132 81
        $mergedData = array_merge(static::getDefaultValues(), $data);
133
134 81
        return DtoPropertiesMapper::for(static::class)->map($mergedData, $this->getFlags());
135
    }
136
137
    /**
138
     * Retrieve a nested value following the dot notation
139
     *
140
     * @param string $property
141
     * @param mixed $value
142
     * @return array
143
     */
144 2
    protected function resolveNestedValue(string $property, $value): array
145
    {
146 2
        if (strpos($property, '.') === false) {
147 2
            return [$property => $value];
148
        }
149
150 1
        [$property, $nestedProperty] = explode('.', $property, 2);
151
152 1
        return [$property => $this->resolveNestedValue($nestedProperty, $value)];
153
    }
154
}
155