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 (#96)
by Ross
15:04 queued 12:23
created

UsesPHPMetaDataTrait::getShortName()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
eloc 2
dl 0
loc 4
ccs 0
cts 0
cp 0
rs 10
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php declare(strict_types=1);
2
3
namespace EdmondsCommerce\DoctrineStaticMeta\Entity\Traits;
4
5
use Doctrine\Common\Util\Debug;
6
use Doctrine\Common\Util\Inflector;
7
use Doctrine\ORM\Mapping\Builder\ClassMetadataBuilder;
8
use Doctrine\ORM\Mapping\ClassMetadata;
9
use Doctrine\ORM\Mapping\ClassMetadata as DoctrineClassMetaData;
10
use EdmondsCommerce\DoctrineStaticMeta\CodeGeneration\Generator\AbstractGenerator;
11
use EdmondsCommerce\DoctrineStaticMeta\Entity\Interfaces\UsesPHPMetaDataInterface;
12
use EdmondsCommerce\DoctrineStaticMeta\Exception\DoctrineStaticMetaException;
13
use EdmondsCommerce\DoctrineStaticMeta\MappingHelper;
14
15
trait UsesPHPMetaDataTrait
16
{
17
18
    /**
19
     * @var \ts\Reflection\ReflectionClass
20
     */
21
    private static $reflectionClass;
22
23
    /**
24
     * @var ClassMetadata
25
     */
26
    private static $metaData;
27
28
    /**
29
     * @var string
30
     */
31
    private static $singular;
32
33
    /**
34
     * @var string
35
     */
36
    private static $plural;
37
38
    /**
39
     * @var array
40
     */
41
    private static $setters;
42
43
    /**
44
     * @var array
45
     */
46
    private static $getters;
47
48
    /**
49
     * Loads the class and property meta data in the class
50
     *
51
     * This is the method called by Doctrine to load the meta data
52
     *
53
     * @param DoctrineClassMetaData $metadata
54
     *
55
     * @throws DoctrineStaticMetaException
56
     * @SuppressWarnings(PHPMD.StaticAccess)
57
     */
58 58
    public static function loadMetadata(DoctrineClassMetaData $metadata): void
59
    {
60
        try {
61 58
            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...
62 58
            $builder                 = new ClassMetadataBuilder($metadata);
63 58
            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...
64 58
            static::loadPropertyDoctrineMetaData($builder);
65 58
            static::loadClassDoctrineMetaData($builder);
66 58
            static::setChangeTrackingPolicy($builder);
67
        } catch (\Exception $e) {
68
            throw new DoctrineStaticMetaException(
69
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
70
                $e->getCode(),
71
                $e
72
            );
73
        }
74 58
    }
75
76
    /**
77
     * This method will reflect on the entity class and pull out all the methods that begin with
78
     * UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
79
     *
80
     * Once it has an array of methods, it calls them all, passing in the $builder
81
     *
82
     * @param ClassMetadataBuilder $builder
83
     *
84
     * @throws DoctrineStaticMetaException
85
     * @SuppressWarnings(PHPMD.StaticAccess)
86
     */
87 58
    protected static function loadPropertyDoctrineMetaData(ClassMetadataBuilder $builder): void
88
    {
89 58
        $methodName = '__no_method__';
90
        try {
91 58
            $staticMethods = static::getStaticMethods();
92
            //now loop through and call them
93 58
            foreach ($staticMethods as $method) {
94 58
                $methodName = $method->getName();
95 58
                if (0 === stripos(
96 58
                    $methodName,
97 58
                    UsesPHPMetaDataInterface::METHOD_PREFIX_GET_PROPERTY_DOCTRINE_META
98
                )
99
                ) {
100 58
                    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 58
        }
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 75
     */
122
    protected static function getStaticMethods(): array
123 75
    {
124
        $reflectionClass = static::getReflectionClass();
125 75
        $staticMethods = $reflectionClass->getMethods(
126 75
            \ReflectionMethod::IS_STATIC
127
        );
128
        // get static methods from traits
129
        $traits = $reflectionClass->getTraits();
130 75
        foreach ($traits as $trait) {
131 75
            if ($trait->getShortName() === 'UsesPHPMetaData') {
132
                continue;
133
            }
134 75
            $traitStaticMethods = $trait->getMethods(
135 75
                \ReflectionMethod::IS_STATIC
136 75
            );
137
            array_merge(
138
                $staticMethods,
139 75
                $traitStaticMethods
140 75
            );
141
        }
142 75
143 75
        return $staticMethods;
144 75
    }
145
146
    /**
147
     * Get class level meta data, eg table name, custom repository
148 75
     *
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 58
    }
159
160 58
    /**
161 58
     * Setting the change policy to be Notify - best performance
162 58
     *
163 58
     * @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 58
    /**
173
     * Get the property name the Entity is mapped by when plural
174 58
     *
175 58
     * 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
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:34
Loading history...
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...
185
                $singular       = static::getSingular();
186 9
                static::$plural = Inflector::pluralize($singular);
187
            }
188
189 9
            return static::$plural;
190 9
        } catch (\Exception $e) {
191 9
            throw new DoctrineStaticMetaException(
192
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
193
                $e->getCode(),
194 9
                $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:29
Loading history...
210
                $reflectionClass = static::getReflectionClass();
211 10
212
                $shortName         = $reflectionClass->getShortName();
213
                $singularShortName = Inflector::singularize($shortName);
214 10
215 9
                $namespaceName   = $reflectionClass->getNamespaceName();
216 8
                $namespaceParts  = \explode(AbstractGenerator::ENTITIES_FOLDER_NAME, $namespaceName);
217
                $entityNamespace = \array_pop($namespaceParts);
218
219 9
                $namespacedShortName = \preg_replace(
220 9
                    '/\\\\/',
221
                    '',
222 9
                    $entityNamespace . $singularShortName
223 9
                );
224 9
225
                static::$singular = \lcfirst($namespacedShortName);
226 9
            }
227 9
228 9
            return static::$singular;
229 9
        } catch (\Exception $e) {
230
            throw new DoctrineStaticMetaException(
231
                'Exception in ' . __METHOD__ . ': ' . $e->getMessage(),
232 9
                $e->getCode(),
233
                $e
234
            );
235 10
        }
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 2
     *
253
     * @param ClassMetadataBuilder $builder
254 2
     *
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
     */
264
    public function getSetters(): array
265
    {
266
        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:39
Loading history...
267
            return static::$setters;
268
        }
269
        $skip            = [
270
            'setChangeTrackingPolicy' => true,
271 2
        ];
272
        static::$setters = [];
273 2
        $reflectionClass = static::getReflectionClass();
274 1
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
275
            $methodName = $method->getName();
276
            if (isset($skip[$methodName])) {
277 2
                continue;
278
            }
279 2
            if (\ts\stringStartsWith($methodName, 'set')) {
280 2
                static::$setters[] = $methodName;
281 2
                continue;
282 2
            }
283 2
            if (\ts\stringStartsWith($methodName, 'add')) {
284
                static::$setters[] = $methodName;
285 2
                continue;
286 2
            }
287 2
        }
288
289 2
        return static::$setters;
290 1
    }
291 2
292
    /**
293
     * Get the short name (without fully qualified namespace) of the current Entity
294
     *
295 2
     * @return string
296
     */
297
    public function getShortName(): string
298
    {
299
        $reflectionClass = static::getReflectionClass();
300
        return $reflectionClass->getShortName();
301
    }
302
303 2
    /**
304
     * @return string
305 2
     * @SuppressWarnings(PHPMD.StaticAccess)
306
     * @SuppressWarnings(PHPMD.ElseExpression)
307
     */
308
    public function __toString(): string
309
    {
310
        $dump          = [];
311
        $metaData = static::$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...
312
        if ($metaData === null) {
313 4
            return 'Could not get metadata for ' . get_class($this);
314
        }
315 4
        $fieldMappings = static::$metaData->fieldMappings;
316 4
        foreach ($this->getGetters() as $getter) {
317 4
            $got       = $this->$getter();
318 4
            $fieldName = \lcfirst(\substr($getter, 3));
319 4
            if (isset($fieldMappings[$fieldName])
320 4
                && 'decimal' === $fieldMappings[$fieldName]['type']
321 4
            ) {
322
                $value = (float) $got;
323 1
            } elseif ($got instanceof \Doctrine\ORM\Proxy\Proxy) {
324 4
                $value = 'Proxy class ';
325
            } elseif (\is_object($got) && method_exists($got, '__toString')) {
326 4
                $value = $got->__toString();
327
            } else {
328
                $value = Debug::export($got, 2);
329 4
            }
330
            $dump[$getter] = $value;
331 4
        }
332
333
        return (string)print_r($dump, true);
334 4
    }
335
336
    /**
337
     * Get an array of getters by name
338
     * [];
339
     *
340
     * @return array|string[]
341
     */
342
    public function getGetters(): array
343 5
    {
344
        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:44
Loading history...
345 5
            return static::$getters;
346 3
        }
347
        $skip = [
348
            'getPlural'    => true,
349 5
            'getSingular'  => true,
350
            'getSetters'   => true,
351
            'getGetters'   => true,
352
            'getIdField'   => true,
353
            'getShortName' => true,
354
        ];
355
356
        static::$getters = [];
357 5
        $reflectionClass = static::getReflectionClass();
358 5
        foreach ($reflectionClass->getMethods(\ReflectionMethod::IS_PUBLIC) as $method) {
359 5
            $methodName = $method->getName();
360 5
            if (isset($skip[$methodName])) {
361 5
                continue;
362
            }
363 5
            if (\ts\stringStartsWith($methodName, 'get')) {
364 5
                static::$getters[] = $methodName;
365 5
                continue;
366
            }
367 5
            if (\ts\stringStartsWith($methodName, 'is')) {
368 4
                static::$getters[] = $methodName;
369 4
                continue;
370
            }
371 5
            if (\ts\stringStartsWith($methodName, 'has')) {
372
                static::$getters[] = $methodName;
373 5
                continue;
374
            }
375
        }
376
377 5
        return static::$getters;
378
    }
379
380
    /**
381
     * Find and run all init methods
382
     * - defined in relationship traits and generally to init ArrayCollection properties
383
     *
384
     * @throws \ReflectionException
385
     */
386 76
    protected function runInitMethods(): void
387
    {
388 76
        $reflectionClass = static::getReflectionClass();
389 30
        $methods = $reflectionClass->getMethods(\ReflectionMethod::IS_PRIVATE);
390
        foreach ($methods as $method) {
391 76
            if ($method instanceof \ReflectionMethod) {
392 76
                $method = $method->getName();
393 76
            }
394 76
            if (\ts\stringContains($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
395
                && \ts\stringStartsWith($method, UsesPHPMetaDataInterface::METHOD_PREFIX_INIT)
396 76
            ) {
397 76
                $this->$method();
398
            }
399 76
        }
400
    }
401
402 76
    /**
403
     * This is used to ensure that the reflection class exists. Not there is no return type because this could be either
404
     * the native Reflection class or the type safe one
405
     *
406
     * @return \ts\Reflection\ReflectionClass
407
     * @throws \ReflectionException
408
     */
409
    private static function getReflectionClass()
410
    {
411
        if (!static::$reflectionClass instanceof \ReflectionClass) {
0 ignored issues
show
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...
introduced by
static::reflectionClass is never a sub-type of ReflectionClass. If static::reflectionClass can have other possible types, add them to src/Entity/Traits/UsesPHPMetaDataTrait.php:19.
Loading history...
412
            static::$reflectionClass = new \ts\Reflection\ReflectionClass(static::class);
413
        }
414
415
        return static::$reflectionClass;
416
    }
417
}
418