EntityMetaData::__wakeup()   A
last analyzed

Complexity

Conditions 3
Paths 3

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 5
CRAP Score 3

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 0
dl 0
loc 8
ccs 5
cts 5
cp 1
crap 3
rs 10
c 0
b 0
f 0
1
<?php declare(strict_types=1);
2
3
namespace Igni\Storage\Mapping\MetaData;
4
5
use Igni\Storage\Exception\MappingException;
6
use Igni\Storage\Mapping\Strategy\Id;
7
use ReflectionClass;
8
9
/**
10
 * Keeps information how entity should be mapped.
11
 *
12
 * @package Igni\Storage\Mapping\MetaData
13
 */
14
final class EntityMetaData
15
{
16
    /**
17
     * Entity class (FQCN)
18
     * @var string
19
     */
20
    private $class;
21
22
    /**
23
     * Generated hydrator class name (not FQCN)
24
     * @var string string
25
     */
26
    private $hydratorClassName;
27
28
    /**
29
     * Entity's mapped properties metadata.
30
     * @var PropertyMetaData[]
31
     */
32
    private $properties = [];
33
34
    /**
35
     * @var ReflectionClass
36
     */
37
    private $reflectionClass;
38
39
    /**
40
     * Either name of table or connection or any other namespace
41
     * where entity is stored.
42
     * @var string
43
     */
44
    private $source;
45
46
    /**
47
     * Connection that will be used when no repository is registered
48
     * for the entity.
49
     * @var string
50
     */
51
    private $connection = 'default';
52
53
    /**
54
     * Provides information if entity is embed entity.
55
     * @var bool
56
     */
57
    private $embed = true;
58
59
    /**
60
     * Keeps user defined hydrator's class (FQCN).
61
     * @var string
62
     */
63
    private $customHydrator;
64
65
    /**
66
     * Keeps mapped properties to storage fields.
67
     * @var string[]
68
     */
69
    private $fields = [];
70
71
    /**
72
     * Contains identifier property.
73
     * @var PropertyMetaData|null
74
     */
75
    private $identifier;
76
77
    /**
78
     * @param string $class
79
     *
80
     * @throws \ReflectionException
81
     */
82 29
    public function __construct(string $class)
83
    {
84 29
        $this->class = $class;
85 29
        $this->reflectionClass = new ReflectionClass($class);
86 29
        $this->hydratorClassName = '_' . str_replace('\\', '', $class) . 'Hydrator';
87 29
    }
88
89 3
    public function makeEmbed(): void
90
    {
91 3
        $this->source = null;
92 3
        $this->embed = true;
93 3
    }
94
95 1
    public function isEmbed(): bool
96
    {
97 1
        return $this->embed;
98
    }
99
100
    public function isStorable(): bool
101
    {
102
        return $this->source !== null && $this->hasIdentifier();
103
    }
104
105 24
    public function setSource(string $source): void
106
    {
107 24
        $this->source = $source;
108 24
        $this->embed = false;
109 24
    }
110
111 15
    public function getSource(): string
112
    {
113 15
        return $this->source;
114
    }
115
116 23
    public function setConnection(string $name = 'default'): void
117
    {
118 23
        $this->connection = $name;
119 23
    }
120
121 22
    public function getConnection(): string
122
    {
123 22
        return $this->connection;
124
    }
125
126 24
    public function setCustomHydratorClass(string $className): void
127
    {
128 24
        if (!class_exists($className)) {
129
            throw new MappingException("Cannot set parent hydrator, class (${className}) does not exists.");
130
        }
131
        $this->customHydrator = $className;
132
    }
133
134
    public function definesCustomHydrator(): bool
135
    {
136 25
        return $this->customHydrator !== null;
137
    }
138
139
    public function getCustomHydratorClass(): string
140
    {
141 24
        return $this->customHydrator;
142
    }
143
144
    public function getProperty(string $name): PropertyMetaData
145
    {
146 1
        if (!isset($this->properties[$name])) {
147
            throw new MappingException("Property ${name} is undefined.");
148
        }
149 1
        return $this->properties[$name];
150
    }
151
152
    public function addProperty(PropertyMetaData $property): void
153
    {
154 27
        $this->properties[$property->getName()] = $property;
155 27
        if ($property->getType() === Id::class) {
156 24
            $this->identifier = $property;
157
        }
158 27
    }
159
160
    public function hasIdentifier(): bool
161
    {
162 11
        return $this->identifier !== null;
163
    }
164
165
    public function getIdentifier(): PropertyMetaData
166
    {
167 11
        if (!$this->hasIdentifier()) {
168
            throw new MappingException("Entity {$this->class} defines no identifier.");
169
        }
170
171 11
        return $this->identifier;
172
    }
173
174
    public function getHydratorClassName(): string
175
    {
176 25
        return $this->hydratorClassName;
177
    }
178
179
    public function definesProperties(): bool
180
    {
181 23
        return !empty($this->properties);
182
    }
183
184
    /**
185
     * @return PropertyMetaData[]
186
     */
187
    public function getProperties(): array
188
    {
189 4
        return $this->properties;
190
    }
191
192
    public function getFields(): array
193
    {
194
        return $this->fields;
195
    }
196
197
    public function getClass(): string
198
    {
199 27
        return $this->class;
200
    }
201
202
    public function createInstance(...$arguments)
203
    {
204 1
        if ($arguments) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $arguments of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
205
            return $this->reflectionClass->newInstanceArgs($arguments);
206
        }
207
208 1
        return $this->reflectionClass->newInstanceWithoutConstructor();
209
    }
210
211
    public function __sleep()
212
    {
213
        return [
214 1
            'class',
215
            'hydratorClassName',
216
            'properties',
217
            'source',
218
            'connection',
219
            'customHydrator',
220
        ];
221
    }
222
223
    public function __wakeup()
224
    {
225 1
        $this->reflectionClass = new ReflectionClass($this->class);
226
227 1
        foreach ($this->properties as $property) {
228 1
            $this->fields[] = $property->getFieldName();
229 1
            if ($property->getType() === Id::class) {
230 1
                $this->identifier = $property;
231
            }
232
        }
233 1
    }
234
}
235