Passed
Pull Request — master (#3)
by
unknown
01:41
created

MapperAttributed::getAnnotation()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 5
dl 0
loc 11
rs 10
c 1
b 0
f 0
cc 2
nc 2
nop 0
1
<?php
2
/********************************************************************************
3
 *   Apache License, Version 2.0                                                *
4
 *                                                                              *
5
 *   Copyright [2020] [Nurlan Mukhanov <[email protected]>]                      *
6
 *                                                                              *
7
 *   Licensed under the Apache License, Version 2.0 (the "License");            *
8
 *   you may not use this file except in compliance with the License.           *
9
 *   You may obtain a copy of the License at                                    *
10
 *                                                                              *
11
 *       http://www.apache.org/licenses/LICENSE-2.0                             *
12
 *                                                                              *
13
 *   Unless required by applicable law or agreed to in writing, software        *
14
 *   distributed under the License is distributed on an "AS IS" BASIS,          *
15
 *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   *
16
 *   See the License for the specific language governing permissions and        *
17
 *   limitations under the License.                                             *
18
 *                                                                              *
19
 ********************************************************************************/
20
21
declare(strict_types=1);
22
23
namespace DBD\Entity;
24
25
use DBD\Entity\Common\EntityException;
26
use DBD\Entity\Interfaces\EntityMapper;
27
use ReflectionClass;
28
use ReflectionException;
29
30
31
/**
32
 * Class MapperAttributed
33
 *
34
 * @package DBD\Entity
35
 */
36
class MapperAttributed implements EntityMapper
37
{
38
    use MapperTrait;
0 ignored issues
show
Bug introduced by
The trait DBD\Entity\MapperTrait requires the property $tables which is not provided by DBD\Entity\MapperAttributed.
Loading history...
39
40
    /**
41
     * @throws ReflectionException
42
     */
43
    public function __construct(
44
        protected string $entityClass
45
    ) {
46
        $this->getAllVariables();
47
    }
48
49
    public function name(): string
50
    {
51
        return substr($this->entityClass, strrpos($this->entityClass, '\\') + 1). 'Map';
52
    }
53
54
    public function getEntityClass(): string
55
    {
56
        return $this->entityClass;
57
    }
58
59
    /**
60
     * @return string
61
     * @throws ReflectionException
62
     * @throws EntityException
63
     */
64
    public function getScheme(): string
65
    {
66
        $reflection = new ReflectionClass($this->entityClass);
67
68
        $attributes = $reflection->getAttributes(EntityTable::class);
69
70
        foreach ($attributes as $attribute) {
71
            return $attribute->newInstance()->scheme;
72
        }
73
74
        throw new EntityException('Missing attribute scheme for ' . $this->entityClass);
75
    }
76
77
    /**
78
     * @return string
79
     * @throws EntityException
80
     * @throws ReflectionException
81
     */
82
    public function getTableName(): string
83
    {
84
        $reflection = new ReflectionClass($this->entityClass);
85
86
        $attributes = $reflection->getAttributes(EntityTable::class);
87
88
        foreach ($attributes as $attribute) {
89
            return $attribute->newInstance()->name;
90
        }
91
92
        throw new EntityException('Missing attribute name for ' . $this->entityClass);
93
    }
94
95
    /**
96
     * @return string
97
     * @throws EntityException
98
     * @throws ReflectionException
99
     */
100
    public function getAnnotation(): string
101
    {
102
        $reflection = new ReflectionClass($this->entityClass);
103
104
        $attributes = $reflection->getAttributes(EntityTable::class);
105
106
        foreach ($attributes as $attribute) {
107
            return $attribute->newInstance()->annotation;
108
        }
109
110
        throw new EntityException('Missing attribute annotation for ' . $this->entityClass);
111
    }
112
113
    /**
114
     * @return MapperVariables
115
     * @throws ReflectionException
116
     * @throws EntityException
117
     */
118
    public function getAllVariables(): MapperVariables
119
    {
120
        $thisName = $this->name();
121
122
        if (!isset(MapperCache::me()->allVariables[$thisName])) {
123
            $reflectionClass = new ReflectionClass($this->entityClass);
124
125
            $properties = $reflectionClass->getProperties();
126
127
            /**
128
             * @var Constraint[] $constraints
129
             * @var Embedded[] $embedded
130
             * @var Complex[] $complexes
131
             * @var Column[] $columns
132
             */
133
            $constraints = $embedded = $complexes = $columns = [];
134
135
            foreach ($properties as $property) {
136
                $attributes = $property->getAttributes();
137
138
                foreach ($attributes as $attribute) {
139
                    if ($attribute->getName() === Column::class || is_subclass_of($attribute->getName(), Column::class)) {
140
                        $columns[$property->getName()] = $attribute->newInstance();
141
                    }
142
                    else if ($attribute->getName() === Constraint::class || is_subclass_of($attribute->getName(), Constraint::class)) {
143
                        $constraints[$property->getName()] = $attribute->newInstance();
144
                    }
145
                    else if ($attribute->getName() === Embedded::class || is_subclass_of($attribute->getName(), Embedded::class)) {
146
                        $embedded[$property->getName()] = $attribute->newInstance();
147
                    }
148
                    else if ($attribute->getName() === Complex::class || is_subclass_of($attribute->getName(), Complex::class)) {
149
                        $complexes[$property->getName()] = $attribute->newInstance();
150
                    }
151
                }
152
            }
153
154
            $this->processComplexes($complexes);
155
            $this->processEmbedded($embedded);
156
            $this->processColumns($columns);
157
            $this->processConstraints($constraints, $columns, $embedded, $complexes);
158
        }
159
160
        return MapperCache::me()->allVariables[$thisName];
161
    }
162
163
    /**
164
     * @param Complex[] $complexes
165
     * @return void
166
     */
167
    private function processComplexes(array $complexes): void
168
    {
169
        $thisName = $this->name();
170
171
        if (!isset(MapperCache::me()->complex[$thisName])) {
172
            MapperCache::me()->complex[$thisName] = [];
173
        }
174
175
        foreach ($complexes as $complexName => $complex) {
176
            $this->$complexName = $complex;
177
            MapperCache::me()->complex[$thisName][$complexName] = $this->$complexName;
178
        }
179
    }
180
181
    /**
182
     * @param Embedded[] $embedded
183
     * @return void
184
     */
185
    private function processEmbedded(array $embedded): void
186
    {
187
        $thisName = $this->name();
188
189
        if (!isset(MapperCache::me()->embedded[$thisName])) {
190
            MapperCache::me()->embedded[$thisName] = [];
191
        }
192
193
        foreach ($embedded as $embeddedName => $embeddedValue) {
194
            $this->$embeddedName = $embeddedValue;
195
196
            MapperCache::me()->embedded[$thisName][$embeddedName] = $this->$embeddedName;
197
        }
198
    }
199
200
    /**
201
     * @param Column[] $columns
202
     * @return void
203
     */
204
    private function processColumns(array $columns): void
205
    {
206
        $thisName = $this->name();
207
208
        if (!isset(MapperCache::me()->columns[$thisName])) {
209
            MapperCache::me()->columns[$thisName] = [];
210
        }
211
212
        foreach ($columns as $columnName => $column) {
213
            MapperCache::me()->columns[$thisName][$columnName] = $column;
214
215
            $this->$columnName = $column;
216
        }
217
    }
218
219
    /**
220
     * @param Constraint[] $constraints
221
     * @param Column[] $columns
222
     * @param Embedded[] $embedded
223
     * @param Complex[] $complexes
224
     * @return void
225
     * @throws EntityException
226
     * @throws ReflectionException
227
     */
228
    private function processConstraints(array $constraints, array $columns, array $embedded, array $complexes): void
229
    {
230
        $thisName = $this->name();
231
232
        if (!isset(MapperCache::me()->constraints[$thisName])) {
233
            MapperCache::me()->constraints[$thisName] = [];
234
        }
235
236
        $entityClass = $this->getEntityClass();
237
238
        foreach ($constraints as $constraintName => $constraint) {
239
            if ($entityClass !== View::class && is_string($constraint->localColumn)) {
240
                $constraint->localColumn = $this->findColumnByOriginName($constraint->localColumn);
241
            }
242
243
            MapperCache::me()->constraints[$thisName][$constraintName] = $constraint;
244
        }
245
246
        MapperCache::me()->allVariables[$thisName] = new MapperVariables($columns, $constraints, $embedded, $complexes);
247
248
        foreach (MapperCache::me()->constraints[$thisName] as $constraintName => $constraint) {
249
            $constraint->localTable = $this->getTable();
250
251
            $this->$constraintName = $constraint;
252
        }
253
    }
254
}
255