Passed
Pull Request — master (#33)
by Vincent
06:53
created

AttributeInfo::isNullable()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 1
c 0
b 0
f 0
dl 0
loc 3
ccs 2
cts 2
cp 1
rs 10
cc 2
nc 2
nop 0
crap 2
1
<?php
2
3
namespace Bdf\Prime\Entity\Hydrator\Generator;
4
5
use ReflectionProperty;
6
7
/**
8
 * Store info about attribute
9
 */
10
class AttributeInfo
11
{
12
    /**
13
     * @var string
14
     */
15
    private $name;
16
17
    /**
18
     * @var array
19
     */
20
    private $metadata;
21
22
    /**
23
     * @var AttributesResolver
24
     */
25
    private $resolver;
26
27
    /**
28
     * @var ReflectionProperty|null
29
     */
30
    private $reflection;
31
32
33
    /**
34
     * AttributeInfo constructor.
35
     *
36
     * @param string $name
37
     * @param array $metadata
38
     * @param AttributesResolver $resolver
39
     */
40 113
    public function __construct(string $name, array $metadata, AttributesResolver $resolver)
0 ignored issues
show
Coding Style introduced by
Expected 1 blank line before function; 2 found
Loading history...
41
    {
42 113
        $this->name = $name;
43 113
        $this->metadata = $metadata;
44 113
        $this->resolver = $resolver;
45 113
    }
46
47
    /**
48
     * Check if the attribute is into an embedded object
49
     *
50
     * @return bool
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
51
     */
52 113
    public function isEmbedded()
53
    {
54 113
        return isset($this->metadata['embedded'])
55
            // If the attribute is a root attribute, check only for root embedded entities
56 113
            && (empty($this->metadata['root']) || $this->resolver->hasRootEmbedded($this->metadata['embedded']))
0 ignored issues
show
Coding Style introduced by
Boolean operators are not allowed outside of control structure conditions
Loading history...
57
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
58
    }
59
60
    /**
61
     * Get the embedded metadata
62
     *
63
     * @return EmbeddedInfo
64
     */
65 113
    public function embedded()
66
    {
67 113
        return empty($this->metadata['root'])
68 113
            ? $this->resolver->embedded($this->metadata['embedded'])
0 ignored issues
show
Coding Style introduced by
Inline shorthand IF statement must be declared on a single line
Loading history...
69 113
            : $this->resolver->rootEmbedded($this->metadata['embedded'])
0 ignored issues
show
Coding Style introduced by
Space after closing parenthesis of function call prohibited
Loading history...
70
        ;
0 ignored issues
show
Coding Style introduced by
Space found before semicolon; expected ");" but found ")
;"
Loading history...
71
    }
72
73
    /**
74
     * Get the attribute name
75
     *
76
     * @return string
77
     */
78 113
    public function name()
79
    {
80 113
        return $this->name;
81
    }
82
83
    /**
84
     * Get the property name of the embedded object
85
     *
86
     * @return string
87
     */
88 29
    public function property()
89
    {
90 29
        $finalAttribute = explode('.', $this->name);
91
92 29
        return end($finalAttribute);
93
    }
94
95
    /**
96
     * Get the declared field type
97
     * If there is no declared type (like with root attributes), this method will return null
98
     *
99
     * @return string|null
100
     */
101 27
    public function type()
102
    {
103 27
        return $this->metadata['type'] ?? null;
0 ignored issues
show
Coding Style introduced by
Operation must be bracketed
Loading history...
104
    }
105
106
    /**
107
     * Get the database field name
108
     *
109
     * @return string
110
     */
111 27
    public function field()
112
    {
113 27
        return $this->metadata['field'];
114
    }
115
116
    /**
117
     * Get the class name of the entity which contains the given attribute
118
     *
119
     * @return class-string
0 ignored issues
show
introduced by
Expected "classstring" but found "class-string" for function return type
Loading history...
Documentation Bug introduced by
The doc comment class-string at position 0 could not be parsed: Unknown type name 'class-string' at position 0 in class-string.
Loading history...
120
     */
121 2
    public function containerClassName(): string
122
    {
123 2
        if (!empty($this->metadata['root']) || !$this->isEmbedded()) {
124 1
            return $this->resolver->className();
125
        }
126
127 1
        return $this->embedded()->class(); // @todo polymorph ?
0 ignored issues
show
Coding Style Best Practice introduced by
Comments for TODO tasks are often forgotten in the code; it might be better to use a dedicated issue tracker.
Loading history...
Coding Style introduced by
Comments may not appear after statements
Loading history...
128
    }
129
130
    /**
131
     * Get the php options of the field
132
     */
133 25
    public function phpOptions(): array
134
    {
135 25
        return $this->metadata['phpOptions'];
136
    }
137
138
    /**
139
     * Get the ReflectionProperty instance for the current attribute
140
     *
141
     * @return ReflectionProperty
142
     * @throws \ReflectionException
143
     */
144 2
    public function reflection(): ReflectionProperty
145
    {
146 2
        if (!$this->reflection) {
147 2
            $this->reflection = new ReflectionProperty($this->containerClassName(), $this->property());
148
        }
149
150 2
        return $this->reflection;
151
    }
152
153
    /**
154
     * Check if the property on the entity is typed (PHP >= 7.4)
155
     *
156
     * @return bool true if a type is defined
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
157
     *
158
     * @throws \ReflectionException
159
     */
160 27
    public function isTyped(): bool
161
    {
162 27
        if (PHP_VERSION_ID < 70400) {
163 27
            return false;
164
        }
165
166
        return $this->reflection()->hasType();
167
    }
168
169
    /**
170
     * Check if the property on the entity allows null
171
     * To allow null it must be not typed or with nullable type
172
     *
173
     * @return bool
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
174
     * @throws \ReflectionException
175
     */
176 27
    public function isNullable(): bool
177
    {
178 27
        return !$this->isTyped() || $this->reflection()->getType()->allowsNull();
0 ignored issues
show
Coding Style introduced by
Boolean operators are not allowed outside of control structure conditions
Loading history...
179
    }
180
181
    /**
182
     * Check if the property on the entity has a default value, or is initilized with null
183
     *
184
     * @return bool
0 ignored issues
show
Coding Style introduced by
Expected "boolean" but found "bool" for function return type
Loading history...
185
     * @throws \ReflectionException
186
     */
187 27
    public function isInitializedByDefault(): bool
188
    {
189 27
        return !$this->isTyped() || array_key_exists($this->property(), (new \ReflectionClass($this->containerClassName()))->getDefaultProperties());
0 ignored issues
show
Coding Style introduced by
Boolean operators are not allowed outside of control structure conditions
Loading history...
190
    }
191
}
192