GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Completed
Pull Request — master (#101)
by joseph
18:59
created

UsesPHPMetaDataTrait::getReflectionClass()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 7
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
eloc 3
dl 0
loc 7
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
cc 2
nc 2
nop 0
crap 6
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Entity\Traits;
4
5
use Doctrine\Common\Inflector\Inflector;
6
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
7
use Doctrine\ORM\Mapping\ClassMetadata;
8
use Doctrine\ORM\Mapping\ClassMetadata as DoctrineClassMetaData;
9
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
10
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\UsesPHPMetaDataInterface;
11
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
12
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
13
14
trait UsesPHPMetaDataTrait
15
{
16
17
    /**
18
     * @var \ts\Reflection\ReflectionClass
19
     */
20
    private static $reflectionClass;
21
22
    /**
23
     * @var ClassMetadata
24
     */
25
    private static $metaData;
26
27
    /**
28
     * @var string
29
     */
30
    private static $singular;
31
32
    /**
33
     * @var string
34
     */
35
    private static $plural;
36
37
    /**
38
     * @var array
39
     */
40
    private static $setters;
41
42
    /**
43
     * @var array
44
     */
45
    private static $getters;
46
47
    /**
48
     * Loads the class and property meta data in the class
49
     *
50
     * This is the method called by Doctrine to load the meta data
51
     *
52
     * @param DoctrineClassMetaData $metadata
53
     *
54
     * @throws DoctrineStaticMetaException
55
     * @SuppressWarnings(PHPMD.StaticAccess)
56
     */
57
    public static function loadMetadata(DoctrineClassMetaData $metadata): void
58
    {
59
        try {
60
            static::$metaData        = $metadata;
0 ignored issues
show
Bug introduced by
Since $metaData is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $metaData to at least protected.
Loading history...
61
            $builder                 = new ClassMetadataBuilder($metadata);
62
            static::$reflectionClass = $metadata->getReflectionClass();
0 ignored issues
show
Documentation Bug introduced by
It seems like $metadata->getReflectionClass() of type ReflectionClass is incompatible with the declared type ts\Reflection\ReflectionClass of property $reflectionClass.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
Bug introduced by
Since $reflectionClass is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $reflectionClass to at least protected.
Loading history...
63
            static::loadPropertyDoctrineMetaData($builder);
64
            static::loadClassDoctrineMetaData($builder);
65
            static::setChangeTrackingPolicy($builder);
66
        } catch (\Exception $e) {
67
            throw new DoctrineStaticMetaException(
68
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
69
                $e->getCode(),
70
                $e
71
            );
72
        }
73
    }
74
75
    /**
76
     * This method will reflect on the entity class and pull out all the methods that begin with
77
     * UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
78
     *
79
     * Once it has an array of methods, it calls them all, passing in the $builder
80
     *
81
     * @param ClassMetadataBuilder $builder
82
     *
83
     * @throws DoctrineStaticMetaException
84
     * @throws \ReflectionException
85
     * @SuppressWarnings(PHPMD.StaticAccess)
86
     */
87
    protected static function loadPropertyDoctrineMetaData(ClassMetadataBuilder $builder): void
88
    {
89
        $methodName = '__no_method__';
90
        try {
91
            $staticMethods = static::getStaticMethods();
92
            //now loop through and call them
93
            foreach ($staticMethods as $method) {
94
                $methodName = $method->getName();
95
                if (0 === stripos(
96
                    $methodName,
97
                    UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
98
                )
99
                ) {
100
                    static::$methodName($builder);
101
                }
102
            }
103
        } catch (\Exception $e) {
104
            $reflectionClass = static::getReflectionClass();
105
            throw new DoctrineStaticMetaException(
106
                'Exception in ' . __METHOD__ . 'for '
107
                . $reflectionClass->getName() . "::$methodName\n\n"
108
                . $e->getMessage()
109
            );
110
        }
111
    }
112
113
    /**
114
     * Get an array of all static methods implemented by the current class
115
     *
116
     * Merges trait methods
117
     * Filters out this trait
118
     *
119
     * @return array|\ReflectionMethod[]
120
     * @throws \ReflectionException
121
     */
122
    protected static function getStaticMethods(): array
123
    {
124
        $reflectionClass = static::getReflectionClass();
125
        $staticMethods   = $reflectionClass->getMethods(
126
            \ReflectionMethod::IS_STATIC
127
        );
128
        // get static methods from traits
129
        $traits = $reflectionClass->getTraits();
130
        foreach ($traits as $trait) {
131
            if ($trait->getShortName() === 'UsesPHPMetaData') {
132
                continue;
133
            }
134
            $traitStaticMethods = $trait->getMethods(
135
                \ReflectionMethod::IS_STATIC
136
            );
137
            array_merge(
138
                $staticMethods,
139
                $traitStaticMethods
140
            );
141
        }
142
143
        return $staticMethods;
144
    }
145
146
    /**
147
     * Get class level meta data, eg table name, custom repository
148
     *
149
     * @param ClassMetadataBuilder $builder
150
     *
151
     * @SuppressWarnings(PHPMD.StaticAccess)
152
     */
153
    protected static function loadClassDoctrineMetaData(ClassMetadataBuilder $builder): void
154
    {
155
        $tableName = MappingHelper::getTableNameForEntityFqn(static::class);
156
        $builder->setTable($tableName);
157
        static::setCustomRepositoryClass($builder);
158
    }
159
160
    /**
161
     * Setting the change policy to be Notify - best performance
162
     *
163
     * @see http://doctrine-orm.readthedocs.io/en/latest/reference/change-tracking-policies.html
164
     *
165
     * @param ClassMetadataBuilder $builder
166
     */
167
    public static function setChangeTrackingPolicy(ClassMetadataBuilder $builder): void
168
    {
169
        $builder->setChangeTrackingPolicyNotify();
170
    }
171
172
    /**
173
     * Get the property name the Entity is mapped by when plural
174
     *
175
     * Override it in your entity class if you are using an Entity class name that doesn't pluralize nicely
176
     *
177
     * @return string
178
     * @throws DoctrineStaticMetaException
179
     * @SuppressWarnings(PHPMD.StaticAccess)
180
     */
181
    public static function getPlural(): string
182
    {
183
        try {
184
            if (null === static::$plural) {
0 ignored issues
show
Bug introduced by
Since $plural is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $plural to at least protected.
Loading history...
introduced by
The condition static::plural is always false. If static::plural can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:33
Loading history...
185
                $singular       = static::getSingular();
186
                static::$plural = Inflector::pluralize($singular);
187
            }
188
189
            return static::$plural;
190
        } catch (\Exception $e) {
191
            throw new DoctrineStaticMetaException(
192
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
193
                $e->getCode(),
194
                $e
195
            );
196
        }
197
    }
198
199
    /**
200
     * Get the property the name the Entity is mapped by when singular
201
     *
202
     * @return string
203
     * @throws DoctrineStaticMetaException
204
     * @SuppressWarnings(PHPMD.StaticAccess)
205
     */
206
    public static function getSingular(): string
207
    {
208
        try {
209
            if (null === static::$singular) {
0 ignored issues
show
Bug introduced by
Since $singular is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $singular to at least protected.
Loading history...
introduced by
The condition static::singular is always false. If static::singular can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:28
Loading history...
210
                $reflectionClass = static::getReflectionClass();
211
212
                $shortName         = $reflectionClass->getShortName();
213
                $singularShortName = Inflector::singularize($shortName);
214
215
                $namespaceName   = $reflectionClass->getNamespaceName();
216
                $namespaceParts  = \explode(AbstractGenerator::ENTITIES_FOLDER_NAME, $namespaceName);
217
                $entityNamespace = \array_pop($namespaceParts);
218
219
                $namespacedShortName = \preg_replace(
220
                    '/\\\\/',
221
                    '',
222
                    $entityNamespace . $singularShortName
223
                );
224
225
                static::$singular = \lcfirst($namespacedShortName);
226
            }
227
228
            return static::$singular;
229
        } catch (\Exception $e) {
230
            throw new DoctrineStaticMetaException(
231
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
232
                $e->getCode(),
233
                $e
234
            );
235
        }
236
    }
237
238
    /**
239
     * Which field is being used for ID - will normally be `id` as implemented by
240
     * \EdmondsCommerce\DoctrineStaticMeta\Fields\Traits\IdField
241
     *
242
     * @return string
243
     * @SuppressWarnings(PHPMD.StaticAccess)
244
     */
245
    public static function getIdField(): string
246
    {
247
        return 'id';
248
    }
249
250
    /**
251
     * In the class itself, we need to specify the repository class name
252
     *
253
     * @param ClassMetadataBuilder $builder
254
     *
255
     * @return mixed
256
     */
257
    abstract protected static function setCustomRepositoryClass(ClassMetadataBuilder $builder);
258
259
    /**
260
     * Get an array of setters by name
261
     *
262
     * @return array|string[]
263
     * @throws \ReflectionException
264
     */
265 1
    public function getSetters(): array
266
    {
267 1
        if (null !== static::$setters) {
0 ignored issues
show
Bug introduced by
Since $setters is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $setters to at least protected.
Loading history...
introduced by
The condition static::setters is always true. If static::setters can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:38
Loading history...
268
            return static::$setters;
269
        }
270
        $skip            = [
271 1
            'setChangeTrackingPolicy' => true,
272
        ];
273 1
        static::$setters = [];
274 1
        $reflectionClass = static::getReflectionClass();
275 1
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
276 1
            $methodName = $method->getName();
277 1
            if (isset($skip[$methodName])) {
278 1
                continue;
279
            }
280 1
            if (\ts\stringStartsWith($methodName, 'set')) {
281 1
                static::$setters[] = $methodName;
282 1
                continue;
283
            }
284 1
            if (\ts\stringStartsWith($methodName, 'add')) {
285
                static::$setters[] = $methodName;
286 1
                continue;
287
            }
288
        }
289
290 1
        return static::$setters;
291
    }
292
293
    /**
294
     * Get the short name (without fully qualified namespace) of the current Entity
295
     *
296
     * @return string
297
     * @throws \ReflectionException
298
     */
299
    public function getShortName(): string
300
    {
301
        $reflectionClass = static::getReflectionClass();
302
303
        return $reflectionClass->getShortName();
304
    }
305
306
    /**
307
     * Get an array of getters by name
308
     * [];
309
     *
310
     * @return array|string[]
311
     * @throws \ReflectionException
312
     */
313 1
    public function getGetters(): array
314
    {
315 1
        if (null !== static::$getters) {
0 ignored issues
show
Bug introduced by
Since $getters is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $getters to at least protected.
Loading history...
introduced by
The condition static::getters is always true. If static::getters can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:43
Loading history...
316
            return static::$getters;
317
        }
318
        $skip = [
319 1
            'getPlural'    => true,
320
            'getSingular'  => true,
321
            'getSetters'   => true,
322
            'getGetters'   => true,
323
            'getIdField'   => true,
324
            'getShortName' => true,
325
        ];
326
327 1
        static::$getters = [];
328 1
        $reflectionClass = static::getReflectionClass();
329 1
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
330 1
            $methodName = $method->getName();
331 1
            if (isset($skip[$methodName])) {
332 1
                continue;
333
            }
334 1
            if (\ts\stringStartsWith($methodName, 'get')) {
335 1
                static::$getters[] = $methodName;
336 1
                continue;
337
            }
338 1
            if (\ts\stringStartsWith($methodName, 'is')) {
339
                static::$getters[] = $methodName;
340
                continue;
341
            }
342 1
            if (\ts\stringStartsWith($methodName, 'has')) {
343
                static::$getters[] = $methodName;
344 1
                continue;
345
            }
346
        }
347
348 1
        return static::$getters;
349
    }
350
351
    /**
352
     * Find and run all init methods
353
     * - defined in relationship traits and generally to init ArrayCollection properties
354
     *
355
     * @throws \ReflectionException
356
     */
357
    protected function runInitMethods(): void
358
    {
359
        $reflectionClass = static::getReflectionClass();
360
        $methods         = $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE);
361
        foreach ($methods as $method) {
362
            if ($method instanceof \ReflectionMethod) {
363
                $method = $method->getName();
364
            }
365
            if (\ts\stringContains($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
366
                && \ts\stringStartsWith($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
367
            ) {
368
                $this->$method();
369
            }
370
        }
371
    }
372
373
    /**
374
     * @return \ts\Reflection\ReflectionClass
375
     * @throws \ReflectionException
376
     */
377
    private static function getReflectionClass(): \ts\Reflection\ReflectionClass
378
    {
379
        if (!static::$reflectionClass instanceof \ts\Reflection\ReflectionClass) {
0 ignored issues
show
introduced by
static::reflectionClass is always a sub-type of ts\Reflection\ReflectionClass. If static::reflectionClass can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:18.
Loading history...
Bug introduced by
Since $reflectionClass is declared private, accessing it with static will lead to errors in possible sub-classes; you can either use self, or increase the visibility of $reflectionClass to at least protected.
Loading history...
380
            static::$reflectionClass = new \ts\Reflection\ReflectionClass(static::class);
381
        }
382
383
        return static::$reflectionClass;
384
    }
385
}
386