DtoPropertyTypes::match()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 3
eloc 5
nc 3
nop 1
dl 0
loc 9
ccs 5
cts 5
cp 1
crap 3
rs 10
c 2
b 0
f 0
1
<?php
2
3
namespace Cerbero\Dto;
4
5
use Cerbero\Dto\Manipulators\ArrayConverter;
6
use Cerbero\Dto\Manipulators\ValueConverter;
7
8
/**
9
 * The wrapper for DTO property types.
10
 *
11
 * @property DtoPropertyType[] $all
12
 * @property bool $includeNull
13
 * @property bool $expectCollection
14
 * @property string|null $expectedDto
15
 * @property ValueConverter|null $expectedConverter
16
 * @property string|null $expectedPrimitive
17
 * @property string[] $declaredNames
18
 */
19
class DtoPropertyTypes
20
{
21
    /**
22
     * The DTO property types.
23
     *
24
     * @var DtoPropertyType[]
25
     */
26
    protected $all = [];
27
28
    /**
29
     * Whether one of the types is 'null'.
30
     *
31
     * @var bool
32
     */
33
    protected $includeNull = false;
34
35
    /**
36
     * Whether the types expect a collection.
37
     *
38
     * @var bool
39
     */
40
    protected $expectCollection = false;
41
42
    /**
43
     * The expected DTO.
44
     *
45
     * @var string
46
     */
47
    protected $expectedDto;
48
49
    /**
50
     * The expected value converter.
51
     *
52
     * @var ValueConverter
53
     */
54
    protected $expectedConverter;
55
56
    /**
57
     * The expected primitive type.
58
     *
59
     * @var string
60
     */
61
    protected $expectedPrimitive;
62
63
    /**
64
     * The types name with the [] suffix if collections.
65
     *
66
     * @var array
67
     */
68
    protected $declaredNames = [];
69
70
    /**
71
     * Add the given DTO property type
72
     *
73
     * @param DtoPropertyType $type
74
     * @return self
75
     */
76 102
    public function addType(DtoPropertyType $type): self
77
    {
78 102
        $this->all[] = $type;
79 102
        $this->includeNull = $this->includeNull || $type->name() == 'null';
80 102
        $this->expectCollection = $this->expectCollection || $type->isCollection();
81 102
        $this->expectedDto = $this->getExpectedDto($type);
82 102
        $this->expectedConverter = $this->getExpectedConverter($type);
83 102
        $this->expectedPrimitive = $this->getExpectedPrimitive($type);
84 102
        $this->declaredNames[] = $type->declaredName();
85
86 102
        return $this;
87
    }
88
89
    /**
90
     * Retrieve the expected DTO if any
91
     *
92
     * @param DtoPropertyType $type
93
     * @return string|null
94
     */
95 102
    protected function getExpectedDto(DtoPropertyType $type): ?string
96
    {
97 102
        if ($this->expectedDto) {
98 3
            return $this->expectedDto;
99
        }
100
101 102
        return $type->isDto() ? $type->name() : null;
102
    }
103
104
    /**
105
     * Retrieve the expected value converter
106
     *
107
     * @param DtoPropertyType $type
108
     * @return ValueConverter|null
109
     */
110 102
    protected function getExpectedConverter(DtoPropertyType $type): ?ValueConverter
111
    {
112 102
        if ($this->expectedConverter) {
113 1
            return $this->expectedConverter;
114
        }
115
116 102
        return ArrayConverter::instance()->getConverterByClass($type->name());
117
    }
118
119
    /**
120
     * Retrieve the expected primitive type
121
     *
122
     * @param DtoPropertyType $type
123
     * @return string|null
124
     */
125 102
    protected function getExpectedPrimitive(DtoPropertyType $type): ?string
126
    {
127 102
        if ($this->expectedPrimitive) {
128 71
            return $this->expectedPrimitive;
129
        }
130
131 102
        $typeName = $type->name();
132
        $casts = [
133 102
            'int' => true,
134
            'integer' => true,
135
            'bool' => true,
136
            'boolean' => true,
137
            'float' => true,
138
            'double' => true,
139
            'string' => true,
140
            'array' => true,
141
            'object' => true,
142
        ];
143
144 102
        return isset($casts[$typeName]) ? $typeName : null;
145
    }
146
147
    /**
148
     * Determine whether the given value matches at least one of the property types
149
     *
150
     * @param mixed $value
151
     * @return bool
152
     */
153 76
    public function match($value): bool
154
    {
155 76
        foreach ($this->all as $type) {
156 76
            if ($type->matches($value)) {
157 69
                return true;
158
            }
159
        }
160
161 7
        return false;
162
    }
163
164
    /**
165
     * Retrieve the given property
166
     *
167
     * @param string $name
168
     * @return mixed
169
     */
170 92
    public function __get(string $name)
171
    {
172 92
        return $this->{$name};
173
    }
174
}
175